omp-low.c 413 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835783678377838783978407841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910791179127913791479157916791779187919792079217922792379247925792679277928792979307931793279337934793579367937793879397940794179427943794479457946794779487949795079517952795379547955795679577958795979607961796279637964796579667967796879697970797179727973797479757976797779787979798079817982798379847985798679877988798979907991799279937994799579967997799879998000800180028003800480058006800780088009801080118012801380148015801680178018801980208021802280238024802580268027802880298030803180328033803480358036803780388039804080418042804380448045804680478048804980508051805280538054805580568057805880598060806180628063806480658066806780688069807080718072807380748075807680778078807980808081808280838084808580868087808880898090809180928093809480958096809780988099810081018102810381048105810681078108810981108111811281138114811581168117811881198120812181228123812481258126812781288129813081318132813381348135813681378138813981408141814281438144814581468147814881498150815181528153815481558156815781588159816081618162816381648165816681678168816981708171817281738174817581768177817881798180818181828183818481858186818781888189819081918192819381948195819681978198819982008201820282038204820582068207820882098210821182128213821482158216821782188219822082218222822382248225822682278228822982308231823282338234823582368237823882398240824182428243824482458246824782488249825082518252825382548255825682578258825982608261826282638264826582668267826882698270827182728273827482758276827782788279828082818282828382848285828682878288828982908291829282938294829582968297829882998300830183028303830483058306830783088309831083118312831383148315831683178318831983208321832283238324832583268327832883298330833183328333833483358336833783388339834083418342834383448345834683478348834983508351835283538354835583568357835883598360836183628363836483658366836783688369837083718372837383748375837683778378837983808381838283838384838583868387838883898390839183928393839483958396839783988399840084018402840384048405840684078408840984108411841284138414841584168417841884198420842184228423842484258426842784288429843084318432843384348435843684378438843984408441844284438444844584468447844884498450845184528453845484558456845784588459846084618462846384648465846684678468846984708471847284738474847584768477847884798480848184828483848484858486848784888489849084918492849384948495849684978498849985008501850285038504850585068507850885098510851185128513851485158516851785188519852085218522852385248525852685278528852985308531853285338534853585368537853885398540854185428543854485458546854785488549855085518552855385548555855685578558855985608561856285638564856585668567856885698570857185728573857485758576857785788579858085818582858385848585858685878588858985908591859285938594859585968597859885998600860186028603860486058606860786088609861086118612861386148615861686178618861986208621862286238624862586268627862886298630863186328633863486358636863786388639864086418642864386448645864686478648864986508651865286538654865586568657865886598660866186628663866486658666866786688669867086718672867386748675867686778678867986808681868286838684868586868687868886898690869186928693869486958696869786988699870087018702870387048705870687078708870987108711871287138714871587168717871887198720872187228723872487258726872787288729873087318732873387348735873687378738873987408741874287438744874587468747874887498750875187528753875487558756875787588759876087618762876387648765876687678768876987708771877287738774877587768777877887798780878187828783878487858786878787888789879087918792879387948795879687978798879988008801880288038804880588068807880888098810881188128813881488158816881788188819882088218822882388248825882688278828882988308831883288338834883588368837883888398840884188428843884488458846884788488849885088518852885388548855885688578858885988608861886288638864886588668867886888698870887188728873887488758876887788788879888088818882888388848885888688878888888988908891889288938894889588968897889888998900890189028903890489058906890789088909891089118912891389148915891689178918891989208921892289238924892589268927892889298930893189328933893489358936893789388939894089418942894389448945894689478948894989508951895289538954895589568957895889598960896189628963896489658966896789688969897089718972897389748975897689778978897989808981898289838984898589868987898889898990899189928993899489958996899789988999900090019002900390049005900690079008900990109011901290139014901590169017901890199020902190229023902490259026902790289029903090319032903390349035903690379038903990409041904290439044904590469047904890499050905190529053905490559056905790589059906090619062906390649065906690679068906990709071907290739074907590769077907890799080908190829083908490859086908790889089909090919092909390949095909690979098909991009101910291039104910591069107910891099110911191129113911491159116911791189119912091219122912391249125912691279128912991309131913291339134913591369137913891399140914191429143914491459146914791489149915091519152915391549155915691579158915991609161916291639164916591669167916891699170917191729173917491759176917791789179918091819182918391849185918691879188918991909191919291939194919591969197919891999200920192029203920492059206920792089209921092119212921392149215921692179218921992209221922292239224922592269227922892299230923192329233923492359236923792389239924092419242924392449245924692479248924992509251925292539254925592569257925892599260926192629263926492659266926792689269927092719272927392749275927692779278927992809281928292839284928592869287928892899290929192929293929492959296929792989299930093019302930393049305930693079308930993109311931293139314931593169317931893199320932193229323932493259326932793289329933093319332933393349335933693379338933993409341934293439344934593469347934893499350935193529353935493559356935793589359936093619362936393649365936693679368936993709371937293739374937593769377937893799380938193829383938493859386938793889389939093919392939393949395939693979398939994009401940294039404940594069407940894099410941194129413941494159416941794189419942094219422942394249425942694279428942994309431943294339434943594369437943894399440944194429443944494459446944794489449945094519452945394549455945694579458945994609461946294639464946594669467946894699470947194729473947494759476947794789479948094819482948394849485948694879488948994909491949294939494949594969497949894999500950195029503950495059506950795089509951095119512951395149515951695179518951995209521952295239524952595269527952895299530953195329533953495359536953795389539954095419542954395449545954695479548954995509551955295539554955595569557955895599560956195629563956495659566956795689569957095719572957395749575957695779578957995809581958295839584958595869587958895899590959195929593959495959596959795989599960096019602960396049605960696079608960996109611961296139614961596169617961896199620962196229623962496259626962796289629963096319632963396349635963696379638963996409641964296439644964596469647964896499650965196529653965496559656965796589659966096619662966396649665966696679668966996709671967296739674967596769677967896799680968196829683968496859686968796889689969096919692969396949695969696979698969997009701970297039704970597069707970897099710971197129713971497159716971797189719972097219722972397249725972697279728972997309731973297339734973597369737973897399740974197429743974497459746974797489749975097519752975397549755975697579758975997609761976297639764976597669767976897699770977197729773977497759776977797789779978097819782978397849785978697879788978997909791979297939794979597969797979897999800980198029803980498059806980798089809981098119812981398149815981698179818981998209821982298239824982598269827982898299830983198329833983498359836983798389839984098419842984398449845984698479848984998509851985298539854985598569857985898599860986198629863986498659866986798689869987098719872987398749875987698779878987998809881988298839884988598869887988898899890989198929893989498959896989798989899990099019902990399049905990699079908990999109911991299139914991599169917991899199920992199229923992499259926992799289929993099319932993399349935993699379938993999409941994299439944994599469947994899499950995199529953995499559956995799589959996099619962996399649965996699679968996999709971997299739974997599769977997899799980998199829983998499859986998799889989999099919992999399949995999699979998999910000100011000210003100041000510006100071000810009100101001110012100131001410015100161001710018100191002010021100221002310024100251002610027100281002910030100311003210033100341003510036100371003810039100401004110042100431004410045100461004710048100491005010051100521005310054100551005610057100581005910060100611006210063100641006510066100671006810069100701007110072100731007410075100761007710078100791008010081100821008310084100851008610087100881008910090100911009210093100941009510096100971009810099101001010110102101031010410105101061010710108101091011010111101121011310114101151011610117101181011910120101211012210123101241012510126101271012810129101301013110132101331013410135101361013710138101391014010141101421014310144101451014610147101481014910150101511015210153101541015510156101571015810159101601016110162101631016410165101661016710168101691017010171101721017310174101751017610177101781017910180101811018210183101841018510186101871018810189101901019110192101931019410195101961019710198101991020010201102021020310204102051020610207102081020910210102111021210213102141021510216102171021810219102201022110222102231022410225102261022710228102291023010231102321023310234102351023610237102381023910240102411024210243102441024510246102471024810249102501025110252102531025410255102561025710258102591026010261102621026310264102651026610267102681026910270102711027210273102741027510276102771027810279102801028110282102831028410285102861028710288102891029010291102921029310294102951029610297102981029910300103011030210303103041030510306103071030810309103101031110312103131031410315103161031710318103191032010321103221032310324103251032610327103281032910330103311033210333103341033510336103371033810339103401034110342103431034410345103461034710348103491035010351103521035310354103551035610357103581035910360103611036210363103641036510366103671036810369103701037110372103731037410375103761037710378103791038010381103821038310384103851038610387103881038910390103911039210393103941039510396103971039810399104001040110402104031040410405104061040710408104091041010411104121041310414104151041610417104181041910420104211042210423104241042510426104271042810429104301043110432104331043410435104361043710438104391044010441104421044310444104451044610447104481044910450104511045210453104541045510456104571045810459104601046110462104631046410465104661046710468104691047010471104721047310474104751047610477104781047910480104811048210483104841048510486104871048810489104901049110492104931049410495104961049710498104991050010501105021050310504105051050610507105081050910510105111051210513105141051510516105171051810519105201052110522105231052410525105261052710528105291053010531105321053310534105351053610537105381053910540105411054210543105441054510546105471054810549105501055110552105531055410555105561055710558105591056010561105621056310564105651056610567105681056910570105711057210573105741057510576105771057810579105801058110582105831058410585105861058710588105891059010591105921059310594105951059610597105981059910600106011060210603106041060510606106071060810609106101061110612106131061410615106161061710618106191062010621106221062310624106251062610627106281062910630106311063210633106341063510636106371063810639106401064110642106431064410645106461064710648106491065010651106521065310654106551065610657106581065910660106611066210663106641066510666106671066810669106701067110672106731067410675106761067710678106791068010681106821068310684106851068610687106881068910690106911069210693106941069510696106971069810699107001070110702107031070410705107061070710708107091071010711107121071310714107151071610717107181071910720107211072210723107241072510726107271072810729107301073110732107331073410735107361073710738107391074010741107421074310744107451074610747107481074910750107511075210753107541075510756107571075810759107601076110762107631076410765107661076710768107691077010771107721077310774107751077610777107781077910780107811078210783107841078510786107871078810789107901079110792107931079410795107961079710798107991080010801108021080310804108051080610807108081080910810108111081210813108141081510816108171081810819108201082110822108231082410825108261082710828108291083010831108321083310834108351083610837108381083910840108411084210843108441084510846108471084810849108501085110852108531085410855108561085710858108591086010861108621086310864108651086610867108681086910870108711087210873108741087510876108771087810879108801088110882108831088410885108861088710888108891089010891108921089310894108951089610897108981089910900109011090210903109041090510906109071090810909109101091110912109131091410915109161091710918109191092010921109221092310924109251092610927109281092910930109311093210933109341093510936109371093810939109401094110942109431094410945109461094710948109491095010951109521095310954109551095610957109581095910960109611096210963109641096510966109671096810969109701097110972109731097410975109761097710978109791098010981109821098310984109851098610987109881098910990109911099210993109941099510996109971099810999110001100111002110031100411005110061100711008110091101011011110121101311014110151101611017110181101911020110211102211023110241102511026110271102811029110301103111032110331103411035110361103711038110391104011041110421104311044110451104611047110481104911050110511105211053110541105511056110571105811059110601106111062110631106411065110661106711068110691107011071110721107311074110751107611077110781107911080110811108211083110841108511086110871108811089110901109111092110931109411095110961109711098110991110011101111021110311104111051110611107111081110911110111111111211113111141111511116111171111811119111201112111122111231112411125111261112711128111291113011131111321113311134111351113611137111381113911140111411114211143111441114511146111471114811149111501115111152111531115411155111561115711158111591116011161111621116311164111651116611167111681116911170111711117211173111741117511176111771117811179111801118111182111831118411185111861118711188111891119011191111921119311194111951119611197111981119911200112011120211203112041120511206112071120811209112101121111212112131121411215112161121711218112191122011221112221122311224112251122611227112281122911230112311123211233112341123511236112371123811239112401124111242112431124411245112461124711248112491125011251112521125311254112551125611257112581125911260112611126211263112641126511266112671126811269112701127111272112731127411275112761127711278112791128011281112821128311284112851128611287112881128911290112911129211293112941129511296112971129811299113001130111302113031130411305113061130711308113091131011311113121131311314113151131611317113181131911320113211132211323113241132511326113271132811329113301133111332113331133411335113361133711338113391134011341113421134311344113451134611347113481134911350113511135211353113541135511356113571135811359113601136111362113631136411365113661136711368113691137011371113721137311374113751137611377113781137911380113811138211383113841138511386113871138811389113901139111392113931139411395113961139711398113991140011401114021140311404114051140611407114081140911410114111141211413114141141511416114171141811419114201142111422114231142411425114261142711428114291143011431114321143311434114351143611437114381143911440114411144211443114441144511446114471144811449114501145111452114531145411455114561145711458114591146011461114621146311464114651146611467114681146911470114711147211473114741147511476114771147811479114801148111482114831148411485114861148711488114891149011491114921149311494114951149611497114981149911500115011150211503115041150511506115071150811509115101151111512115131151411515115161151711518115191152011521115221152311524115251152611527115281152911530115311153211533115341153511536115371153811539115401154111542115431154411545115461154711548115491155011551115521155311554115551155611557115581155911560115611156211563115641156511566115671156811569115701157111572115731157411575115761157711578115791158011581115821158311584115851158611587115881158911590115911159211593115941159511596115971159811599116001160111602116031160411605116061160711608116091161011611116121161311614116151161611617116181161911620116211162211623116241162511626116271162811629116301163111632116331163411635116361163711638116391164011641116421164311644116451164611647116481164911650116511165211653116541165511656116571165811659116601166111662116631166411665116661166711668116691167011671116721167311674116751167611677116781167911680116811168211683116841168511686116871168811689116901169111692116931169411695116961169711698116991170011701117021170311704117051170611707117081170911710117111171211713117141171511716117171171811719117201172111722117231172411725117261172711728117291173011731117321173311734117351173611737117381173911740117411174211743117441174511746117471174811749117501175111752117531175411755117561175711758117591176011761117621176311764117651176611767117681176911770117711177211773117741177511776117771177811779117801178111782117831178411785117861178711788117891179011791117921179311794117951179611797117981179911800118011180211803118041180511806118071180811809118101181111812118131181411815118161181711818118191182011821118221182311824118251182611827118281182911830118311183211833118341183511836118371183811839118401184111842118431184411845118461184711848118491185011851118521185311854118551185611857118581185911860118611186211863118641186511866118671186811869118701187111872118731187411875118761187711878118791188011881118821188311884118851188611887118881188911890118911189211893118941189511896118971189811899119001190111902119031190411905119061190711908119091191011911119121191311914119151191611917119181191911920119211192211923119241192511926119271192811929119301193111932119331193411935119361193711938119391194011941119421194311944119451194611947119481194911950119511195211953119541195511956119571195811959119601196111962119631196411965119661196711968119691197011971119721197311974119751197611977119781197911980119811198211983119841198511986119871198811989119901199111992119931199411995119961199711998119991200012001120021200312004120051200612007120081200912010120111201212013120141201512016120171201812019120201202112022120231202412025120261202712028120291203012031120321203312034120351203612037120381203912040120411204212043120441204512046120471204812049120501205112052120531205412055120561205712058120591206012061120621206312064120651206612067120681206912070120711207212073120741207512076120771207812079120801208112082120831208412085120861208712088120891209012091120921209312094120951209612097120981209912100121011210212103121041210512106121071210812109121101211112112121131211412115121161211712118121191212012121121221212312124121251212612127121281212912130121311213212133121341213512136121371213812139121401214112142121431214412145121461214712148121491215012151121521215312154121551215612157121581215912160121611216212163121641216512166121671216812169121701217112172121731217412175121761217712178121791218012181121821218312184121851218612187121881218912190121911219212193121941219512196121971219812199122001220112202122031220412205122061220712208122091221012211122121221312214122151221612217122181221912220122211222212223122241222512226122271222812229122301223112232122331223412235122361223712238122391224012241122421224312244122451224612247122481224912250122511225212253122541225512256122571225812259122601226112262122631226412265122661226712268122691227012271122721227312274122751227612277122781227912280122811228212283122841228512286122871228812289122901229112292122931229412295122961229712298122991230012301123021230312304123051230612307123081230912310123111231212313123141231512316123171231812319123201232112322123231232412325123261232712328123291233012331123321233312334123351233612337123381233912340123411234212343123441234512346123471234812349123501235112352123531235412355123561235712358123591236012361123621236312364123651236612367123681236912370123711237212373123741237512376123771237812379123801238112382123831238412385123861238712388123891239012391123921239312394123951239612397123981239912400124011240212403124041240512406124071240812409124101241112412124131241412415124161241712418124191242012421124221242312424124251242612427124281242912430124311243212433124341243512436124371243812439124401244112442124431244412445124461244712448124491245012451124521245312454124551245612457124581245912460124611246212463124641246512466124671246812469124701247112472124731247412475124761247712478124791248012481124821248312484124851248612487124881248912490124911249212493124941249512496124971249812499125001250112502125031250412505125061250712508125091251012511125121251312514125151251612517125181251912520125211252212523125241252512526125271252812529125301253112532125331253412535125361253712538125391254012541125421254312544125451254612547125481254912550125511255212553125541255512556125571255812559125601256112562125631256412565125661256712568125691257012571125721257312574125751257612577125781257912580125811258212583125841258512586125871258812589125901259112592125931259412595125961259712598125991260012601126021260312604126051260612607126081260912610126111261212613126141261512616126171261812619126201262112622126231262412625126261262712628126291263012631126321263312634126351263612637126381263912640126411264212643126441264512646126471264812649126501265112652126531265412655126561265712658126591266012661126621266312664126651266612667126681266912670126711267212673126741267512676126771267812679126801268112682126831268412685126861268712688126891269012691126921269312694126951269612697126981269912700127011270212703127041270512706127071270812709127101271112712127131271412715127161271712718127191272012721127221272312724127251272612727127281272912730127311273212733127341273512736127371273812739127401274112742127431274412745127461274712748127491275012751127521275312754127551275612757127581275912760127611276212763127641276512766127671276812769127701277112772127731277412775127761277712778127791278012781127821278312784127851278612787127881278912790127911279212793127941279512796127971279812799128001280112802128031280412805128061280712808128091281012811128121281312814128151281612817128181281912820128211282212823128241282512826128271282812829128301283112832128331283412835128361283712838128391284012841128421284312844128451284612847128481284912850128511285212853128541285512856128571285812859128601286112862128631286412865128661286712868128691287012871128721287312874128751287612877128781287912880128811288212883128841288512886128871288812889128901289112892128931289412895128961289712898128991290012901129021290312904129051290612907129081290912910129111291212913129141291512916129171291812919129201292112922129231292412925129261292712928129291293012931129321293312934129351293612937129381293912940129411294212943129441294512946129471294812949129501295112952129531295412955129561295712958129591296012961129621296312964129651296612967129681296912970129711297212973129741297512976129771297812979129801298112982129831298412985129861298712988129891299012991129921299312994129951299612997129981299913000130011300213003130041300513006130071300813009130101301113012130131301413015130161301713018130191302013021130221302313024130251302613027130281302913030130311303213033130341303513036130371303813039130401304113042130431304413045130461304713048130491305013051130521305313054130551305613057130581305913060130611306213063130641306513066130671306813069130701307113072130731307413075130761307713078130791308013081130821308313084130851308613087130881308913090130911309213093130941309513096130971309813099131001310113102131031310413105131061310713108131091311013111131121311313114131151311613117131181311913120131211312213123131241312513126131271312813129131301313113132131331313413135131361313713138131391314013141131421314313144131451314613147131481314913150131511315213153131541315513156131571315813159131601316113162131631316413165131661316713168131691317013171131721317313174131751317613177131781317913180131811318213183131841318513186131871318813189131901319113192131931319413195131961319713198131991320013201132021320313204132051320613207132081320913210132111321213213132141321513216132171321813219132201322113222132231322413225132261322713228132291323013231132321323313234132351323613237132381323913240132411324213243132441324513246132471324813249132501325113252132531325413255132561325713258132591326013261132621326313264132651326613267132681326913270132711327213273132741327513276132771327813279132801328113282132831328413285132861328713288132891329013291132921329313294132951329613297132981329913300133011330213303133041330513306133071330813309133101331113312133131331413315133161331713318133191332013321133221332313324133251332613327133281332913330133311333213333133341333513336133371333813339133401334113342133431334413345133461334713348133491335013351133521335313354133551335613357133581335913360133611336213363133641336513366133671336813369133701337113372133731337413375133761337713378133791338013381133821338313384133851338613387133881338913390133911339213393133941339513396133971339813399134001340113402134031340413405134061340713408134091341013411134121341313414134151341613417134181341913420134211342213423134241342513426134271342813429134301343113432134331343413435134361343713438134391344013441134421344313444134451344613447134481344913450134511345213453134541345513456134571345813459134601346113462134631346413465134661346713468134691347013471134721347313474134751347613477134781347913480134811348213483134841348513486134871348813489134901349113492134931349413495134961349713498134991350013501135021350313504135051350613507135081350913510135111351213513135141351513516135171351813519135201352113522135231352413525135261352713528135291353013531135321353313534135351353613537135381353913540135411354213543135441354513546135471354813549135501355113552135531355413555135561355713558135591356013561135621356313564135651356613567135681356913570135711357213573135741357513576135771357813579135801358113582135831358413585135861358713588135891359013591135921359313594135951359613597135981359913600136011360213603136041360513606136071360813609136101361113612136131361413615136161361713618136191362013621136221362313624136251362613627136281362913630136311363213633136341363513636136371363813639136401364113642136431364413645136461364713648136491365013651136521365313654136551365613657136581365913660136611366213663136641366513666136671366813669136701367113672136731367413675136761367713678136791368013681136821368313684136851368613687136881368913690136911369213693136941369513696136971369813699137001370113702137031370413705137061370713708137091371013711137121371313714137151371613717137181371913720137211372213723137241372513726137271372813729137301373113732137331373413735137361373713738137391374013741137421374313744137451374613747137481374913750137511375213753137541375513756137571375813759137601376113762137631376413765137661376713768137691377013771137721377313774137751377613777137781377913780137811378213783137841378513786137871378813789137901379113792137931379413795137961379713798137991380013801138021380313804138051380613807138081380913810138111381213813138141381513816138171381813819138201382113822138231382413825138261382713828138291383013831138321383313834138351383613837138381383913840138411384213843138441384513846138471384813849138501385113852138531385413855
  1. /* Lowering pass for OMP directives. Converts OMP directives into explicit
  2. calls to the runtime library (libgomp), data marshalling to implement data
  3. sharing and copying clauses, offloading to accelerators, and more.
  4. Contributed by Diego Novillo <dnovillo@redhat.com>
  5. Copyright (C) 2005-2015 Free Software Foundation, Inc.
  6. This file is part of GCC.
  7. GCC is free software; you can redistribute it and/or modify it under
  8. the terms of the GNU General Public License as published by the Free
  9. Software Foundation; either version 3, or (at your option) any later
  10. version.
  11. GCC is distributed in the hope that it will be useful, but WITHOUT ANY
  12. WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13. FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  14. for more details.
  15. You should have received a copy of the GNU General Public License
  16. along with GCC; see the file COPYING3. If not see
  17. <http://www.gnu.org/licenses/>. */
  18. #include "config.h"
  19. #include "system.h"
  20. #include "coretypes.h"
  21. #include "tm.h"
  22. #include "hash-set.h"
  23. #include "machmode.h"
  24. #include "vec.h"
  25. #include "double-int.h"
  26. #include "input.h"
  27. #include "alias.h"
  28. #include "symtab.h"
  29. #include "wide-int.h"
  30. #include "inchash.h"
  31. #include "tree.h"
  32. #include "fold-const.h"
  33. #include "stringpool.h"
  34. #include "stor-layout.h"
  35. #include "rtl.h"
  36. #include "predict.h"
  37. #include "hard-reg-set.h"
  38. #include "function.h"
  39. #include "dominance.h"
  40. #include "cfg.h"
  41. #include "cfganal.h"
  42. #include "basic-block.h"
  43. #include "tree-ssa-alias.h"
  44. #include "internal-fn.h"
  45. #include "gimple-fold.h"
  46. #include "gimple-expr.h"
  47. #include "is-a.h"
  48. #include "gimple.h"
  49. #include "gimplify.h"
  50. #include "gimple-iterator.h"
  51. #include "gimplify-me.h"
  52. #include "gimple-walk.h"
  53. #include "tree-iterator.h"
  54. #include "tree-inline.h"
  55. #include "langhooks.h"
  56. #include "diagnostic-core.h"
  57. #include "gimple-ssa.h"
  58. #include "hash-map.h"
  59. #include "plugin-api.h"
  60. #include "ipa-ref.h"
  61. #include "cgraph.h"
  62. #include "tree-cfg.h"
  63. #include "tree-phinodes.h"
  64. #include "ssa-iterators.h"
  65. #include "tree-ssanames.h"
  66. #include "tree-into-ssa.h"
  67. #include "hashtab.h"
  68. #include "flags.h"
  69. #include "statistics.h"
  70. #include "real.h"
  71. #include "fixed-value.h"
  72. #include "insn-config.h"
  73. #include "expmed.h"
  74. #include "dojump.h"
  75. #include "explow.h"
  76. #include "calls.h"
  77. #include "emit-rtl.h"
  78. #include "varasm.h"
  79. #include "stmt.h"
  80. #include "expr.h"
  81. #include "tree-dfa.h"
  82. #include "tree-ssa.h"
  83. #include "tree-pass.h"
  84. #include "except.h"
  85. #include "splay-tree.h"
  86. #include "insn-codes.h"
  87. #include "optabs.h"
  88. #include "cfgloop.h"
  89. #include "target.h"
  90. #include "common/common-target.h"
  91. #include "omp-low.h"
  92. #include "gimple-low.h"
  93. #include "tree-cfgcleanup.h"
  94. #include "pretty-print.h"
  95. #include "alloc-pool.h"
  96. #include "symbol-summary.h"
  97. #include "ipa-prop.h"
  98. #include "tree-nested.h"
  99. #include "tree-eh.h"
  100. #include "cilk.h"
  101. #include "context.h"
  102. #include "lto-section-names.h"
  103. #include "gomp-constants.h"
  104. /* Lowering of OMP parallel and workshare constructs proceeds in two
  105. phases. The first phase scans the function looking for OMP statements
  106. and then for variables that must be replaced to satisfy data sharing
  107. clauses. The second phase expands code for the constructs, as well as
  108. re-gimplifying things when variables have been replaced with complex
  109. expressions.
  110. Final code generation is done by pass_expand_omp. The flowgraph is
  111. scanned for regions which are then moved to a new
  112. function, to be invoked by the thread library, or offloaded. */
  113. /* OMP region information. Every parallel and workshare
  114. directive is enclosed between two markers, the OMP_* directive
  115. and a corresponding OMP_RETURN statement. */
  116. struct omp_region
  117. {
  118. /* The enclosing region. */
  119. struct omp_region *outer;
  120. /* First child region. */
  121. struct omp_region *inner;
  122. /* Next peer region. */
  123. struct omp_region *next;
  124. /* Block containing the omp directive as its last stmt. */
  125. basic_block entry;
  126. /* Block containing the OMP_RETURN as its last stmt. */
  127. basic_block exit;
  128. /* Block containing the OMP_CONTINUE as its last stmt. */
  129. basic_block cont;
  130. /* If this is a combined parallel+workshare region, this is a list
  131. of additional arguments needed by the combined parallel+workshare
  132. library call. */
  133. vec<tree, va_gc> *ws_args;
  134. /* The code for the omp directive of this region. */
  135. enum gimple_code type;
  136. /* Schedule kind, only used for OMP_FOR type regions. */
  137. enum omp_clause_schedule_kind sched_kind;
  138. /* True if this is a combined parallel+workshare region. */
  139. bool is_combined_parallel;
  140. };
  141. /* Levels of parallelism as defined by OpenACC. Increasing numbers
  142. correspond to deeper loop nesting levels. */
  143. #define MASK_GANG 1
  144. #define MASK_WORKER 2
  145. #define MASK_VECTOR 4
  146. /* Context structure. Used to store information about each parallel
  147. directive in the code. */
  148. typedef struct omp_context
  149. {
  150. /* This field must be at the beginning, as we do "inheritance": Some
  151. callback functions for tree-inline.c (e.g., omp_copy_decl)
  152. receive a copy_body_data pointer that is up-casted to an
  153. omp_context pointer. */
  154. copy_body_data cb;
  155. /* The tree of contexts corresponding to the encountered constructs. */
  156. struct omp_context *outer;
  157. gimple stmt;
  158. /* Map variables to fields in a structure that allows communication
  159. between sending and receiving threads. */
  160. splay_tree field_map;
  161. tree record_type;
  162. tree sender_decl;
  163. tree receiver_decl;
  164. /* These are used just by task contexts, if task firstprivate fn is
  165. needed. srecord_type is used to communicate from the thread
  166. that encountered the task construct to task firstprivate fn,
  167. record_type is allocated by GOMP_task, initialized by task firstprivate
  168. fn and passed to the task body fn. */
  169. splay_tree sfield_map;
  170. tree srecord_type;
  171. /* A chain of variables to add to the top-level block surrounding the
  172. construct. In the case of a parallel, this is in the child function. */
  173. tree block_vars;
  174. /* A map of reduction pointer variables. For accelerators, each
  175. reduction variable is replaced with an array. Each thread, in turn,
  176. is assigned to a slot on that array. */
  177. splay_tree reduction_map;
  178. /* Label to which GOMP_cancel{,llation_point} and explicit and implicit
  179. barriers should jump to during omplower pass. */
  180. tree cancel_label;
  181. /* What to do with variables with implicitly determined sharing
  182. attributes. */
  183. enum omp_clause_default_kind default_kind;
  184. /* Nesting depth of this context. Used to beautify error messages re
  185. invalid gotos. The outermost ctx is depth 1, with depth 0 being
  186. reserved for the main body of the function. */
  187. int depth;
  188. /* True if this parallel directive is nested within another. */
  189. bool is_nested;
  190. /* True if this construct can be cancelled. */
  191. bool cancellable;
  192. /* For OpenACC loops, a mask of gang, worker and vector used at
  193. levels below this one. */
  194. int gwv_below;
  195. /* For OpenACC loops, a mask of gang, worker and vector used at
  196. this level and above. For parallel and kernels clauses, a mask
  197. indicating which of num_gangs/num_workers/num_vectors was used. */
  198. int gwv_this;
  199. } omp_context;
  200. /* A structure holding the elements of:
  201. for (V = N1; V cond N2; V += STEP) [...] */
  202. struct omp_for_data_loop
  203. {
  204. tree v, n1, n2, step;
  205. enum tree_code cond_code;
  206. };
  207. /* A structure describing the main elements of a parallel loop. */
  208. struct omp_for_data
  209. {
  210. struct omp_for_data_loop loop;
  211. tree chunk_size;
  212. gomp_for *for_stmt;
  213. tree pre, iter_type;
  214. int collapse;
  215. bool have_nowait, have_ordered;
  216. enum omp_clause_schedule_kind sched_kind;
  217. struct omp_for_data_loop *loops;
  218. };
  219. static splay_tree all_contexts;
  220. static int taskreg_nesting_level;
  221. static int target_nesting_level;
  222. static struct omp_region *root_omp_region;
  223. static bitmap task_shared_vars;
  224. static vec<omp_context *> taskreg_contexts;
  225. static void scan_omp (gimple_seq *, omp_context *);
  226. static tree scan_omp_1_op (tree *, int *, void *);
  227. #define WALK_SUBSTMTS \
  228. case GIMPLE_BIND: \
  229. case GIMPLE_TRY: \
  230. case GIMPLE_CATCH: \
  231. case GIMPLE_EH_FILTER: \
  232. case GIMPLE_TRANSACTION: \
  233. /* The sub-statements for these should be walked. */ \
  234. *handled_ops_p = false; \
  235. break;
  236. /* Helper function to get the name of the array containing the partial
  237. reductions for OpenACC reductions. */
  238. static const char *
  239. oacc_get_reduction_array_id (tree node)
  240. {
  241. const char *id = IDENTIFIER_POINTER (DECL_NAME (node));
  242. int len = strlen ("OACC") + strlen (id);
  243. char *temp_name = XALLOCAVEC (char, len + 1);
  244. snprintf (temp_name, len + 1, "OACC%s", id);
  245. return IDENTIFIER_POINTER (get_identifier (temp_name));
  246. }
  247. /* Determine the number of threads OpenACC threads used to determine the
  248. size of the array of partial reductions. Currently, this is num_gangs
  249. * vector_length. This value may be different than GOACC_GET_NUM_THREADS,
  250. because it is independed of the device used. */
  251. static tree
  252. oacc_max_threads (omp_context *ctx)
  253. {
  254. tree nthreads, vector_length, gangs, clauses;
  255. gangs = fold_convert (sizetype, integer_one_node);
  256. vector_length = gangs;
  257. /* The reduction clause may be nested inside a loop directive.
  258. Scan for the innermost vector_length clause. */
  259. for (omp_context *oc = ctx; oc; oc = oc->outer)
  260. {
  261. if (gimple_code (oc->stmt) != GIMPLE_OMP_TARGET
  262. || (gimple_omp_target_kind (oc->stmt)
  263. != GF_OMP_TARGET_KIND_OACC_PARALLEL))
  264. continue;
  265. clauses = gimple_omp_target_clauses (oc->stmt);
  266. vector_length = find_omp_clause (clauses, OMP_CLAUSE_VECTOR_LENGTH);
  267. if (vector_length)
  268. vector_length = fold_convert_loc (OMP_CLAUSE_LOCATION (vector_length),
  269. sizetype,
  270. OMP_CLAUSE_VECTOR_LENGTH_EXPR
  271. (vector_length));
  272. else
  273. vector_length = fold_convert (sizetype, integer_one_node);
  274. gangs = find_omp_clause (clauses, OMP_CLAUSE_NUM_GANGS);
  275. if (gangs)
  276. gangs = fold_convert_loc (OMP_CLAUSE_LOCATION (gangs), sizetype,
  277. OMP_CLAUSE_NUM_GANGS_EXPR (gangs));
  278. else
  279. gangs = fold_convert (sizetype, integer_one_node);
  280. break;
  281. }
  282. nthreads = fold_build2 (MULT_EXPR, sizetype, gangs, vector_length);
  283. return nthreads;
  284. }
  285. /* Holds offload tables with decls. */
  286. vec<tree, va_gc> *offload_funcs, *offload_vars;
  287. /* Convenience function for calling scan_omp_1_op on tree operands. */
  288. static inline tree
  289. scan_omp_op (tree *tp, omp_context *ctx)
  290. {
  291. struct walk_stmt_info wi;
  292. memset (&wi, 0, sizeof (wi));
  293. wi.info = ctx;
  294. wi.want_locations = true;
  295. return walk_tree (tp, scan_omp_1_op, &wi, NULL);
  296. }
  297. static void lower_omp (gimple_seq *, omp_context *);
  298. static tree lookup_decl_in_outer_ctx (tree, omp_context *);
  299. static tree maybe_lookup_decl_in_outer_ctx (tree, omp_context *);
  300. /* Find an OMP clause of type KIND within CLAUSES. */
  301. tree
  302. find_omp_clause (tree clauses, enum omp_clause_code kind)
  303. {
  304. for (; clauses ; clauses = OMP_CLAUSE_CHAIN (clauses))
  305. if (OMP_CLAUSE_CODE (clauses) == kind)
  306. return clauses;
  307. return NULL_TREE;
  308. }
  309. /* Return true if CTX is for an omp parallel. */
  310. static inline bool
  311. is_parallel_ctx (omp_context *ctx)
  312. {
  313. return gimple_code (ctx->stmt) == GIMPLE_OMP_PARALLEL;
  314. }
  315. /* Return true if CTX is for an omp task. */
  316. static inline bool
  317. is_task_ctx (omp_context *ctx)
  318. {
  319. return gimple_code (ctx->stmt) == GIMPLE_OMP_TASK;
  320. }
  321. /* Return true if CTX is for an omp parallel or omp task. */
  322. static inline bool
  323. is_taskreg_ctx (omp_context *ctx)
  324. {
  325. return gimple_code (ctx->stmt) == GIMPLE_OMP_PARALLEL
  326. || gimple_code (ctx->stmt) == GIMPLE_OMP_TASK;
  327. }
  328. /* Return true if REGION is a combined parallel+workshare region. */
  329. static inline bool
  330. is_combined_parallel (struct omp_region *region)
  331. {
  332. return region->is_combined_parallel;
  333. }
  334. /* Extract the header elements of parallel loop FOR_STMT and store
  335. them into *FD. */
  336. static void
  337. extract_omp_for_data (gomp_for *for_stmt, struct omp_for_data *fd,
  338. struct omp_for_data_loop *loops)
  339. {
  340. tree t, var, *collapse_iter, *collapse_count;
  341. tree count = NULL_TREE, iter_type = long_integer_type_node;
  342. struct omp_for_data_loop *loop;
  343. int i;
  344. struct omp_for_data_loop dummy_loop;
  345. location_t loc = gimple_location (for_stmt);
  346. bool simd = gimple_omp_for_kind (for_stmt) & GF_OMP_FOR_SIMD;
  347. bool distribute = gimple_omp_for_kind (for_stmt)
  348. == GF_OMP_FOR_KIND_DISTRIBUTE;
  349. fd->for_stmt = for_stmt;
  350. fd->pre = NULL;
  351. fd->collapse = gimple_omp_for_collapse (for_stmt);
  352. if (fd->collapse > 1)
  353. fd->loops = loops;
  354. else
  355. fd->loops = &fd->loop;
  356. fd->have_nowait = distribute || simd;
  357. fd->have_ordered = false;
  358. fd->sched_kind = OMP_CLAUSE_SCHEDULE_STATIC;
  359. fd->chunk_size = NULL_TREE;
  360. if (gimple_omp_for_kind (fd->for_stmt) == GF_OMP_FOR_KIND_CILKFOR)
  361. fd->sched_kind = OMP_CLAUSE_SCHEDULE_CILKFOR;
  362. collapse_iter = NULL;
  363. collapse_count = NULL;
  364. for (t = gimple_omp_for_clauses (for_stmt); t ; t = OMP_CLAUSE_CHAIN (t))
  365. switch (OMP_CLAUSE_CODE (t))
  366. {
  367. case OMP_CLAUSE_NOWAIT:
  368. fd->have_nowait = true;
  369. break;
  370. case OMP_CLAUSE_ORDERED:
  371. fd->have_ordered = true;
  372. break;
  373. case OMP_CLAUSE_SCHEDULE:
  374. gcc_assert (!distribute);
  375. fd->sched_kind = OMP_CLAUSE_SCHEDULE_KIND (t);
  376. fd->chunk_size = OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (t);
  377. break;
  378. case OMP_CLAUSE_DIST_SCHEDULE:
  379. gcc_assert (distribute);
  380. fd->chunk_size = OMP_CLAUSE_DIST_SCHEDULE_CHUNK_EXPR (t);
  381. break;
  382. case OMP_CLAUSE_COLLAPSE:
  383. if (fd->collapse > 1)
  384. {
  385. collapse_iter = &OMP_CLAUSE_COLLAPSE_ITERVAR (t);
  386. collapse_count = &OMP_CLAUSE_COLLAPSE_COUNT (t);
  387. }
  388. break;
  389. default:
  390. break;
  391. }
  392. /* FIXME: for now map schedule(auto) to schedule(static).
  393. There should be analysis to determine whether all iterations
  394. are approximately the same amount of work (then schedule(static)
  395. is best) or if it varies (then schedule(dynamic,N) is better). */
  396. if (fd->sched_kind == OMP_CLAUSE_SCHEDULE_AUTO)
  397. {
  398. fd->sched_kind = OMP_CLAUSE_SCHEDULE_STATIC;
  399. gcc_assert (fd->chunk_size == NULL);
  400. }
  401. gcc_assert (fd->collapse == 1 || collapse_iter != NULL);
  402. if (fd->sched_kind == OMP_CLAUSE_SCHEDULE_RUNTIME)
  403. gcc_assert (fd->chunk_size == NULL);
  404. else if (fd->chunk_size == NULL)
  405. {
  406. /* We only need to compute a default chunk size for ordered
  407. static loops and dynamic loops. */
  408. if (fd->sched_kind != OMP_CLAUSE_SCHEDULE_STATIC
  409. || fd->have_ordered)
  410. fd->chunk_size = (fd->sched_kind == OMP_CLAUSE_SCHEDULE_STATIC)
  411. ? integer_zero_node : integer_one_node;
  412. }
  413. for (i = 0; i < fd->collapse; i++)
  414. {
  415. if (fd->collapse == 1)
  416. loop = &fd->loop;
  417. else if (loops != NULL)
  418. loop = loops + i;
  419. else
  420. loop = &dummy_loop;
  421. loop->v = gimple_omp_for_index (for_stmt, i);
  422. gcc_assert (SSA_VAR_P (loop->v));
  423. gcc_assert (TREE_CODE (TREE_TYPE (loop->v)) == INTEGER_TYPE
  424. || TREE_CODE (TREE_TYPE (loop->v)) == POINTER_TYPE);
  425. var = TREE_CODE (loop->v) == SSA_NAME ? SSA_NAME_VAR (loop->v) : loop->v;
  426. loop->n1 = gimple_omp_for_initial (for_stmt, i);
  427. loop->cond_code = gimple_omp_for_cond (for_stmt, i);
  428. loop->n2 = gimple_omp_for_final (for_stmt, i);
  429. switch (loop->cond_code)
  430. {
  431. case LT_EXPR:
  432. case GT_EXPR:
  433. break;
  434. case NE_EXPR:
  435. gcc_assert (gimple_omp_for_kind (for_stmt)
  436. == GF_OMP_FOR_KIND_CILKSIMD
  437. || (gimple_omp_for_kind (for_stmt)
  438. == GF_OMP_FOR_KIND_CILKFOR));
  439. break;
  440. case LE_EXPR:
  441. if (POINTER_TYPE_P (TREE_TYPE (loop->n2)))
  442. loop->n2 = fold_build_pointer_plus_hwi_loc (loc, loop->n2, 1);
  443. else
  444. loop->n2 = fold_build2_loc (loc,
  445. PLUS_EXPR, TREE_TYPE (loop->n2), loop->n2,
  446. build_int_cst (TREE_TYPE (loop->n2), 1));
  447. loop->cond_code = LT_EXPR;
  448. break;
  449. case GE_EXPR:
  450. if (POINTER_TYPE_P (TREE_TYPE (loop->n2)))
  451. loop->n2 = fold_build_pointer_plus_hwi_loc (loc, loop->n2, -1);
  452. else
  453. loop->n2 = fold_build2_loc (loc,
  454. MINUS_EXPR, TREE_TYPE (loop->n2), loop->n2,
  455. build_int_cst (TREE_TYPE (loop->n2), 1));
  456. loop->cond_code = GT_EXPR;
  457. break;
  458. default:
  459. gcc_unreachable ();
  460. }
  461. t = gimple_omp_for_incr (for_stmt, i);
  462. gcc_assert (TREE_OPERAND (t, 0) == var);
  463. switch (TREE_CODE (t))
  464. {
  465. case PLUS_EXPR:
  466. loop->step = TREE_OPERAND (t, 1);
  467. break;
  468. case POINTER_PLUS_EXPR:
  469. loop->step = fold_convert (ssizetype, TREE_OPERAND (t, 1));
  470. break;
  471. case MINUS_EXPR:
  472. loop->step = TREE_OPERAND (t, 1);
  473. loop->step = fold_build1_loc (loc,
  474. NEGATE_EXPR, TREE_TYPE (loop->step),
  475. loop->step);
  476. break;
  477. default:
  478. gcc_unreachable ();
  479. }
  480. if (simd
  481. || (fd->sched_kind == OMP_CLAUSE_SCHEDULE_STATIC
  482. && !fd->have_ordered))
  483. {
  484. if (fd->collapse == 1)
  485. iter_type = TREE_TYPE (loop->v);
  486. else if (i == 0
  487. || TYPE_PRECISION (iter_type)
  488. < TYPE_PRECISION (TREE_TYPE (loop->v)))
  489. iter_type
  490. = build_nonstandard_integer_type
  491. (TYPE_PRECISION (TREE_TYPE (loop->v)), 1);
  492. }
  493. else if (iter_type != long_long_unsigned_type_node)
  494. {
  495. if (POINTER_TYPE_P (TREE_TYPE (loop->v)))
  496. iter_type = long_long_unsigned_type_node;
  497. else if (TYPE_UNSIGNED (TREE_TYPE (loop->v))
  498. && TYPE_PRECISION (TREE_TYPE (loop->v))
  499. >= TYPE_PRECISION (iter_type))
  500. {
  501. tree n;
  502. if (loop->cond_code == LT_EXPR)
  503. n = fold_build2_loc (loc,
  504. PLUS_EXPR, TREE_TYPE (loop->v),
  505. loop->n2, loop->step);
  506. else
  507. n = loop->n1;
  508. if (TREE_CODE (n) != INTEGER_CST
  509. || tree_int_cst_lt (TYPE_MAX_VALUE (iter_type), n))
  510. iter_type = long_long_unsigned_type_node;
  511. }
  512. else if (TYPE_PRECISION (TREE_TYPE (loop->v))
  513. > TYPE_PRECISION (iter_type))
  514. {
  515. tree n1, n2;
  516. if (loop->cond_code == LT_EXPR)
  517. {
  518. n1 = loop->n1;
  519. n2 = fold_build2_loc (loc,
  520. PLUS_EXPR, TREE_TYPE (loop->v),
  521. loop->n2, loop->step);
  522. }
  523. else
  524. {
  525. n1 = fold_build2_loc (loc,
  526. MINUS_EXPR, TREE_TYPE (loop->v),
  527. loop->n2, loop->step);
  528. n2 = loop->n1;
  529. }
  530. if (TREE_CODE (n1) != INTEGER_CST
  531. || TREE_CODE (n2) != INTEGER_CST
  532. || !tree_int_cst_lt (TYPE_MIN_VALUE (iter_type), n1)
  533. || !tree_int_cst_lt (n2, TYPE_MAX_VALUE (iter_type)))
  534. iter_type = long_long_unsigned_type_node;
  535. }
  536. }
  537. if (collapse_count && *collapse_count == NULL)
  538. {
  539. t = fold_binary (loop->cond_code, boolean_type_node,
  540. fold_convert (TREE_TYPE (loop->v), loop->n1),
  541. fold_convert (TREE_TYPE (loop->v), loop->n2));
  542. if (t && integer_zerop (t))
  543. count = build_zero_cst (long_long_unsigned_type_node);
  544. else if ((i == 0 || count != NULL_TREE)
  545. && TREE_CODE (TREE_TYPE (loop->v)) == INTEGER_TYPE
  546. && TREE_CONSTANT (loop->n1)
  547. && TREE_CONSTANT (loop->n2)
  548. && TREE_CODE (loop->step) == INTEGER_CST)
  549. {
  550. tree itype = TREE_TYPE (loop->v);
  551. if (POINTER_TYPE_P (itype))
  552. itype = signed_type_for (itype);
  553. t = build_int_cst (itype, (loop->cond_code == LT_EXPR ? -1 : 1));
  554. t = fold_build2_loc (loc,
  555. PLUS_EXPR, itype,
  556. fold_convert_loc (loc, itype, loop->step), t);
  557. t = fold_build2_loc (loc, PLUS_EXPR, itype, t,
  558. fold_convert_loc (loc, itype, loop->n2));
  559. t = fold_build2_loc (loc, MINUS_EXPR, itype, t,
  560. fold_convert_loc (loc, itype, loop->n1));
  561. if (TYPE_UNSIGNED (itype) && loop->cond_code == GT_EXPR)
  562. t = fold_build2_loc (loc, TRUNC_DIV_EXPR, itype,
  563. fold_build1_loc (loc, NEGATE_EXPR, itype, t),
  564. fold_build1_loc (loc, NEGATE_EXPR, itype,
  565. fold_convert_loc (loc, itype,
  566. loop->step)));
  567. else
  568. t = fold_build2_loc (loc, TRUNC_DIV_EXPR, itype, t,
  569. fold_convert_loc (loc, itype, loop->step));
  570. t = fold_convert_loc (loc, long_long_unsigned_type_node, t);
  571. if (count != NULL_TREE)
  572. count = fold_build2_loc (loc,
  573. MULT_EXPR, long_long_unsigned_type_node,
  574. count, t);
  575. else
  576. count = t;
  577. if (TREE_CODE (count) != INTEGER_CST)
  578. count = NULL_TREE;
  579. }
  580. else if (count && !integer_zerop (count))
  581. count = NULL_TREE;
  582. }
  583. }
  584. if (count
  585. && !simd
  586. && (fd->sched_kind != OMP_CLAUSE_SCHEDULE_STATIC
  587. || fd->have_ordered))
  588. {
  589. if (!tree_int_cst_lt (count, TYPE_MAX_VALUE (long_integer_type_node)))
  590. iter_type = long_long_unsigned_type_node;
  591. else
  592. iter_type = long_integer_type_node;
  593. }
  594. else if (collapse_iter && *collapse_iter != NULL)
  595. iter_type = TREE_TYPE (*collapse_iter);
  596. fd->iter_type = iter_type;
  597. if (collapse_iter && *collapse_iter == NULL)
  598. *collapse_iter = create_tmp_var (iter_type, ".iter");
  599. if (collapse_count && *collapse_count == NULL)
  600. {
  601. if (count)
  602. *collapse_count = fold_convert_loc (loc, iter_type, count);
  603. else
  604. *collapse_count = create_tmp_var (iter_type, ".count");
  605. }
  606. if (fd->collapse > 1)
  607. {
  608. fd->loop.v = *collapse_iter;
  609. fd->loop.n1 = build_int_cst (TREE_TYPE (fd->loop.v), 0);
  610. fd->loop.n2 = *collapse_count;
  611. fd->loop.step = build_int_cst (TREE_TYPE (fd->loop.v), 1);
  612. fd->loop.cond_code = LT_EXPR;
  613. }
  614. /* For OpenACC loops, force a chunk size of one, as this avoids the default
  615. scheduling where several subsequent iterations are being executed by the
  616. same thread. */
  617. if (gimple_omp_for_kind (for_stmt) == GF_OMP_FOR_KIND_OACC_LOOP)
  618. {
  619. gcc_assert (fd->chunk_size == NULL_TREE);
  620. fd->chunk_size = build_int_cst (TREE_TYPE (fd->loop.v), 1);
  621. }
  622. }
  623. /* Given two blocks PAR_ENTRY_BB and WS_ENTRY_BB such that WS_ENTRY_BB
  624. is the immediate dominator of PAR_ENTRY_BB, return true if there
  625. are no data dependencies that would prevent expanding the parallel
  626. directive at PAR_ENTRY_BB as a combined parallel+workshare region.
  627. When expanding a combined parallel+workshare region, the call to
  628. the child function may need additional arguments in the case of
  629. GIMPLE_OMP_FOR regions. In some cases, these arguments are
  630. computed out of variables passed in from the parent to the child
  631. via 'struct .omp_data_s'. For instance:
  632. #pragma omp parallel for schedule (guided, i * 4)
  633. for (j ...)
  634. Is lowered into:
  635. # BLOCK 2 (PAR_ENTRY_BB)
  636. .omp_data_o.i = i;
  637. #pragma omp parallel [child fn: bar.omp_fn.0 ( ..., D.1598)
  638. # BLOCK 3 (WS_ENTRY_BB)
  639. .omp_data_i = &.omp_data_o;
  640. D.1667 = .omp_data_i->i;
  641. D.1598 = D.1667 * 4;
  642. #pragma omp for schedule (guided, D.1598)
  643. When we outline the parallel region, the call to the child function
  644. 'bar.omp_fn.0' will need the value D.1598 in its argument list, but
  645. that value is computed *after* the call site. So, in principle we
  646. cannot do the transformation.
  647. To see whether the code in WS_ENTRY_BB blocks the combined
  648. parallel+workshare call, we collect all the variables used in the
  649. GIMPLE_OMP_FOR header check whether they appear on the LHS of any
  650. statement in WS_ENTRY_BB. If so, then we cannot emit the combined
  651. call.
  652. FIXME. If we had the SSA form built at this point, we could merely
  653. hoist the code in block 3 into block 2 and be done with it. But at
  654. this point we don't have dataflow information and though we could
  655. hack something up here, it is really not worth the aggravation. */
  656. static bool
  657. workshare_safe_to_combine_p (basic_block ws_entry_bb)
  658. {
  659. struct omp_for_data fd;
  660. gimple ws_stmt = last_stmt (ws_entry_bb);
  661. if (gimple_code (ws_stmt) == GIMPLE_OMP_SECTIONS)
  662. return true;
  663. gcc_assert (gimple_code (ws_stmt) == GIMPLE_OMP_FOR);
  664. extract_omp_for_data (as_a <gomp_for *> (ws_stmt), &fd, NULL);
  665. if (fd.collapse > 1 && TREE_CODE (fd.loop.n2) != INTEGER_CST)
  666. return false;
  667. if (fd.iter_type != long_integer_type_node)
  668. return false;
  669. /* FIXME. We give up too easily here. If any of these arguments
  670. are not constants, they will likely involve variables that have
  671. been mapped into fields of .omp_data_s for sharing with the child
  672. function. With appropriate data flow, it would be possible to
  673. see through this. */
  674. if (!is_gimple_min_invariant (fd.loop.n1)
  675. || !is_gimple_min_invariant (fd.loop.n2)
  676. || !is_gimple_min_invariant (fd.loop.step)
  677. || (fd.chunk_size && !is_gimple_min_invariant (fd.chunk_size)))
  678. return false;
  679. return true;
  680. }
  681. /* Collect additional arguments needed to emit a combined
  682. parallel+workshare call. WS_STMT is the workshare directive being
  683. expanded. */
  684. static vec<tree, va_gc> *
  685. get_ws_args_for (gimple par_stmt, gimple ws_stmt)
  686. {
  687. tree t;
  688. location_t loc = gimple_location (ws_stmt);
  689. vec<tree, va_gc> *ws_args;
  690. if (gomp_for *for_stmt = dyn_cast <gomp_for *> (ws_stmt))
  691. {
  692. struct omp_for_data fd;
  693. tree n1, n2;
  694. extract_omp_for_data (for_stmt, &fd, NULL);
  695. n1 = fd.loop.n1;
  696. n2 = fd.loop.n2;
  697. if (gimple_omp_for_combined_into_p (for_stmt))
  698. {
  699. tree innerc
  700. = find_omp_clause (gimple_omp_parallel_clauses (par_stmt),
  701. OMP_CLAUSE__LOOPTEMP_);
  702. gcc_assert (innerc);
  703. n1 = OMP_CLAUSE_DECL (innerc);
  704. innerc = find_omp_clause (OMP_CLAUSE_CHAIN (innerc),
  705. OMP_CLAUSE__LOOPTEMP_);
  706. gcc_assert (innerc);
  707. n2 = OMP_CLAUSE_DECL (innerc);
  708. }
  709. vec_alloc (ws_args, 3 + (fd.chunk_size != 0));
  710. t = fold_convert_loc (loc, long_integer_type_node, n1);
  711. ws_args->quick_push (t);
  712. t = fold_convert_loc (loc, long_integer_type_node, n2);
  713. ws_args->quick_push (t);
  714. t = fold_convert_loc (loc, long_integer_type_node, fd.loop.step);
  715. ws_args->quick_push (t);
  716. if (fd.chunk_size)
  717. {
  718. t = fold_convert_loc (loc, long_integer_type_node, fd.chunk_size);
  719. ws_args->quick_push (t);
  720. }
  721. return ws_args;
  722. }
  723. else if (gimple_code (ws_stmt) == GIMPLE_OMP_SECTIONS)
  724. {
  725. /* Number of sections is equal to the number of edges from the
  726. GIMPLE_OMP_SECTIONS_SWITCH statement, except for the one to
  727. the exit of the sections region. */
  728. basic_block bb = single_succ (gimple_bb (ws_stmt));
  729. t = build_int_cst (unsigned_type_node, EDGE_COUNT (bb->succs) - 1);
  730. vec_alloc (ws_args, 1);
  731. ws_args->quick_push (t);
  732. return ws_args;
  733. }
  734. gcc_unreachable ();
  735. }
  736. /* Discover whether REGION is a combined parallel+workshare region. */
  737. static void
  738. determine_parallel_type (struct omp_region *region)
  739. {
  740. basic_block par_entry_bb, par_exit_bb;
  741. basic_block ws_entry_bb, ws_exit_bb;
  742. if (region == NULL || region->inner == NULL
  743. || region->exit == NULL || region->inner->exit == NULL
  744. || region->inner->cont == NULL)
  745. return;
  746. /* We only support parallel+for and parallel+sections. */
  747. if (region->type != GIMPLE_OMP_PARALLEL
  748. || (region->inner->type != GIMPLE_OMP_FOR
  749. && region->inner->type != GIMPLE_OMP_SECTIONS))
  750. return;
  751. /* Check for perfect nesting PAR_ENTRY_BB -> WS_ENTRY_BB and
  752. WS_EXIT_BB -> PAR_EXIT_BB. */
  753. par_entry_bb = region->entry;
  754. par_exit_bb = region->exit;
  755. ws_entry_bb = region->inner->entry;
  756. ws_exit_bb = region->inner->exit;
  757. if (single_succ (par_entry_bb) == ws_entry_bb
  758. && single_succ (ws_exit_bb) == par_exit_bb
  759. && workshare_safe_to_combine_p (ws_entry_bb)
  760. && (gimple_omp_parallel_combined_p (last_stmt (par_entry_bb))
  761. || (last_and_only_stmt (ws_entry_bb)
  762. && last_and_only_stmt (par_exit_bb))))
  763. {
  764. gimple par_stmt = last_stmt (par_entry_bb);
  765. gimple ws_stmt = last_stmt (ws_entry_bb);
  766. if (region->inner->type == GIMPLE_OMP_FOR)
  767. {
  768. /* If this is a combined parallel loop, we need to determine
  769. whether or not to use the combined library calls. There
  770. are two cases where we do not apply the transformation:
  771. static loops and any kind of ordered loop. In the first
  772. case, we already open code the loop so there is no need
  773. to do anything else. In the latter case, the combined
  774. parallel loop call would still need extra synchronization
  775. to implement ordered semantics, so there would not be any
  776. gain in using the combined call. */
  777. tree clauses = gimple_omp_for_clauses (ws_stmt);
  778. tree c = find_omp_clause (clauses, OMP_CLAUSE_SCHEDULE);
  779. if (c == NULL
  780. || OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_STATIC
  781. || find_omp_clause (clauses, OMP_CLAUSE_ORDERED))
  782. {
  783. region->is_combined_parallel = false;
  784. region->inner->is_combined_parallel = false;
  785. return;
  786. }
  787. }
  788. region->is_combined_parallel = true;
  789. region->inner->is_combined_parallel = true;
  790. region->ws_args = get_ws_args_for (par_stmt, ws_stmt);
  791. }
  792. }
  793. /* Return true if EXPR is variable sized. */
  794. static inline bool
  795. is_variable_sized (const_tree expr)
  796. {
  797. return !TREE_CONSTANT (TYPE_SIZE_UNIT (TREE_TYPE (expr)));
  798. }
  799. /* Return true if DECL is a reference type. */
  800. static inline bool
  801. is_reference (tree decl)
  802. {
  803. return lang_hooks.decls.omp_privatize_by_reference (decl);
  804. }
  805. /* Return the type of a decl. If the decl is reference type,
  806. return its base type. */
  807. static inline tree
  808. get_base_type (tree decl)
  809. {
  810. tree type = TREE_TYPE (decl);
  811. if (is_reference (decl))
  812. type = TREE_TYPE (type);
  813. return type;
  814. }
  815. /* Lookup variables. The "maybe" form
  816. allows for the variable form to not have been entered, otherwise we
  817. assert that the variable must have been entered. */
  818. static inline tree
  819. lookup_decl (tree var, omp_context *ctx)
  820. {
  821. tree *n = ctx->cb.decl_map->get (var);
  822. return *n;
  823. }
  824. static inline tree
  825. maybe_lookup_decl (const_tree var, omp_context *ctx)
  826. {
  827. tree *n = ctx->cb.decl_map->get (const_cast<tree> (var));
  828. return n ? *n : NULL_TREE;
  829. }
  830. static inline tree
  831. lookup_field (tree var, omp_context *ctx)
  832. {
  833. splay_tree_node n;
  834. n = splay_tree_lookup (ctx->field_map, (splay_tree_key) var);
  835. return (tree) n->value;
  836. }
  837. static inline tree
  838. lookup_sfield (tree var, omp_context *ctx)
  839. {
  840. splay_tree_node n;
  841. n = splay_tree_lookup (ctx->sfield_map
  842. ? ctx->sfield_map : ctx->field_map,
  843. (splay_tree_key) var);
  844. return (tree) n->value;
  845. }
  846. static inline tree
  847. maybe_lookup_field (tree var, omp_context *ctx)
  848. {
  849. splay_tree_node n;
  850. n = splay_tree_lookup (ctx->field_map, (splay_tree_key) var);
  851. return n ? (tree) n->value : NULL_TREE;
  852. }
  853. static inline tree
  854. lookup_oacc_reduction (const char *id, omp_context *ctx)
  855. {
  856. splay_tree_node n;
  857. n = splay_tree_lookup (ctx->reduction_map, (splay_tree_key) id);
  858. return (tree) n->value;
  859. }
  860. static inline tree
  861. maybe_lookup_oacc_reduction (tree var, omp_context *ctx)
  862. {
  863. splay_tree_node n = NULL;
  864. if (ctx->reduction_map)
  865. n = splay_tree_lookup (ctx->reduction_map, (splay_tree_key) var);
  866. return n ? (tree) n->value : NULL_TREE;
  867. }
  868. /* Return true if DECL should be copied by pointer. SHARED_CTX is
  869. the parallel context if DECL is to be shared. */
  870. static bool
  871. use_pointer_for_field (tree decl, omp_context *shared_ctx)
  872. {
  873. if (AGGREGATE_TYPE_P (TREE_TYPE (decl)))
  874. return true;
  875. /* We can only use copy-in/copy-out semantics for shared variables
  876. when we know the value is not accessible from an outer scope. */
  877. if (shared_ctx)
  878. {
  879. gcc_assert (!is_gimple_omp_oacc (shared_ctx->stmt));
  880. /* ??? Trivially accessible from anywhere. But why would we even
  881. be passing an address in this case? Should we simply assert
  882. this to be false, or should we have a cleanup pass that removes
  883. these from the list of mappings? */
  884. if (TREE_STATIC (decl) || DECL_EXTERNAL (decl))
  885. return true;
  886. /* For variables with DECL_HAS_VALUE_EXPR_P set, we cannot tell
  887. without analyzing the expression whether or not its location
  888. is accessible to anyone else. In the case of nested parallel
  889. regions it certainly may be. */
  890. if (TREE_CODE (decl) != RESULT_DECL && DECL_HAS_VALUE_EXPR_P (decl))
  891. return true;
  892. /* Do not use copy-in/copy-out for variables that have their
  893. address taken. */
  894. if (TREE_ADDRESSABLE (decl))
  895. return true;
  896. /* lower_send_shared_vars only uses copy-in, but not copy-out
  897. for these. */
  898. if (TREE_READONLY (decl)
  899. || ((TREE_CODE (decl) == RESULT_DECL
  900. || TREE_CODE (decl) == PARM_DECL)
  901. && DECL_BY_REFERENCE (decl)))
  902. return false;
  903. /* Disallow copy-in/out in nested parallel if
  904. decl is shared in outer parallel, otherwise
  905. each thread could store the shared variable
  906. in its own copy-in location, making the
  907. variable no longer really shared. */
  908. if (shared_ctx->is_nested)
  909. {
  910. omp_context *up;
  911. for (up = shared_ctx->outer; up; up = up->outer)
  912. if (is_taskreg_ctx (up) && maybe_lookup_decl (decl, up))
  913. break;
  914. if (up)
  915. {
  916. tree c;
  917. for (c = gimple_omp_taskreg_clauses (up->stmt);
  918. c; c = OMP_CLAUSE_CHAIN (c))
  919. if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
  920. && OMP_CLAUSE_DECL (c) == decl)
  921. break;
  922. if (c)
  923. goto maybe_mark_addressable_and_ret;
  924. }
  925. }
  926. /* For tasks avoid using copy-in/out. As tasks can be
  927. deferred or executed in different thread, when GOMP_task
  928. returns, the task hasn't necessarily terminated. */
  929. if (is_task_ctx (shared_ctx))
  930. {
  931. tree outer;
  932. maybe_mark_addressable_and_ret:
  933. outer = maybe_lookup_decl_in_outer_ctx (decl, shared_ctx);
  934. if (is_gimple_reg (outer))
  935. {
  936. /* Taking address of OUTER in lower_send_shared_vars
  937. might need regimplification of everything that uses the
  938. variable. */
  939. if (!task_shared_vars)
  940. task_shared_vars = BITMAP_ALLOC (NULL);
  941. bitmap_set_bit (task_shared_vars, DECL_UID (outer));
  942. TREE_ADDRESSABLE (outer) = 1;
  943. }
  944. return true;
  945. }
  946. }
  947. return false;
  948. }
  949. /* Construct a new automatic decl similar to VAR. */
  950. static tree
  951. omp_copy_decl_2 (tree var, tree name, tree type, omp_context *ctx)
  952. {
  953. tree copy = copy_var_decl (var, name, type);
  954. DECL_CONTEXT (copy) = current_function_decl;
  955. DECL_CHAIN (copy) = ctx->block_vars;
  956. ctx->block_vars = copy;
  957. return copy;
  958. }
  959. static tree
  960. omp_copy_decl_1 (tree var, omp_context *ctx)
  961. {
  962. return omp_copy_decl_2 (var, DECL_NAME (var), TREE_TYPE (var), ctx);
  963. }
  964. /* Build COMPONENT_REF and set TREE_THIS_VOLATILE and TREE_READONLY on it
  965. as appropriate. */
  966. static tree
  967. omp_build_component_ref (tree obj, tree field)
  968. {
  969. tree ret = build3 (COMPONENT_REF, TREE_TYPE (field), obj, field, NULL);
  970. if (TREE_THIS_VOLATILE (field))
  971. TREE_THIS_VOLATILE (ret) |= 1;
  972. if (TREE_READONLY (field))
  973. TREE_READONLY (ret) |= 1;
  974. return ret;
  975. }
  976. /* Build tree nodes to access the field for VAR on the receiver side. */
  977. static tree
  978. build_receiver_ref (tree var, bool by_ref, omp_context *ctx)
  979. {
  980. tree x, field = lookup_field (var, ctx);
  981. /* If the receiver record type was remapped in the child function,
  982. remap the field into the new record type. */
  983. x = maybe_lookup_field (field, ctx);
  984. if (x != NULL)
  985. field = x;
  986. x = build_simple_mem_ref (ctx->receiver_decl);
  987. x = omp_build_component_ref (x, field);
  988. if (by_ref)
  989. x = build_simple_mem_ref (x);
  990. return x;
  991. }
  992. /* Build tree nodes to access VAR in the scope outer to CTX. In the case
  993. of a parallel, this is a component reference; for workshare constructs
  994. this is some variable. */
  995. static tree
  996. build_outer_var_ref (tree var, omp_context *ctx)
  997. {
  998. tree x;
  999. if (is_global_var (maybe_lookup_decl_in_outer_ctx (var, ctx)))
  1000. x = var;
  1001. else if (is_variable_sized (var))
  1002. {
  1003. x = TREE_OPERAND (DECL_VALUE_EXPR (var), 0);
  1004. x = build_outer_var_ref (x, ctx);
  1005. x = build_simple_mem_ref (x);
  1006. }
  1007. else if (is_taskreg_ctx (ctx))
  1008. {
  1009. bool by_ref = use_pointer_for_field (var, NULL);
  1010. x = build_receiver_ref (var, by_ref, ctx);
  1011. }
  1012. else if (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
  1013. && gimple_omp_for_kind (ctx->stmt) & GF_OMP_FOR_SIMD)
  1014. {
  1015. /* #pragma omp simd isn't a worksharing construct, and can reference even
  1016. private vars in its linear etc. clauses. */
  1017. x = NULL_TREE;
  1018. if (ctx->outer && is_taskreg_ctx (ctx))
  1019. x = lookup_decl (var, ctx->outer);
  1020. else if (ctx->outer)
  1021. x = maybe_lookup_decl_in_outer_ctx (var, ctx);
  1022. if (x == NULL_TREE)
  1023. x = var;
  1024. }
  1025. else if (ctx->outer)
  1026. x = lookup_decl (var, ctx->outer);
  1027. else if (is_reference (var))
  1028. /* This can happen with orphaned constructs. If var is reference, it is
  1029. possible it is shared and as such valid. */
  1030. x = var;
  1031. else
  1032. gcc_unreachable ();
  1033. if (is_reference (var))
  1034. x = build_simple_mem_ref (x);
  1035. return x;
  1036. }
  1037. /* Build tree nodes to access the field for VAR on the sender side. */
  1038. static tree
  1039. build_sender_ref (tree var, omp_context *ctx)
  1040. {
  1041. tree field = lookup_sfield (var, ctx);
  1042. return omp_build_component_ref (ctx->sender_decl, field);
  1043. }
  1044. /* Add a new field for VAR inside the structure CTX->SENDER_DECL. */
  1045. static void
  1046. install_var_field (tree var, bool by_ref, int mask, omp_context *ctx)
  1047. {
  1048. tree field, type, sfield = NULL_TREE;
  1049. gcc_assert ((mask & 1) == 0
  1050. || !splay_tree_lookup (ctx->field_map, (splay_tree_key) var));
  1051. gcc_assert ((mask & 2) == 0 || !ctx->sfield_map
  1052. || !splay_tree_lookup (ctx->sfield_map, (splay_tree_key) var));
  1053. gcc_assert ((mask & 3) == 3
  1054. || !is_gimple_omp_oacc (ctx->stmt));
  1055. type = TREE_TYPE (var);
  1056. if (mask & 4)
  1057. {
  1058. gcc_assert (TREE_CODE (type) == ARRAY_TYPE);
  1059. type = build_pointer_type (build_pointer_type (type));
  1060. }
  1061. else if (by_ref)
  1062. type = build_pointer_type (type);
  1063. else if ((mask & 3) == 1 && is_reference (var))
  1064. type = TREE_TYPE (type);
  1065. field = build_decl (DECL_SOURCE_LOCATION (var),
  1066. FIELD_DECL, DECL_NAME (var), type);
  1067. /* Remember what variable this field was created for. This does have a
  1068. side effect of making dwarf2out ignore this member, so for helpful
  1069. debugging we clear it later in delete_omp_context. */
  1070. DECL_ABSTRACT_ORIGIN (field) = var;
  1071. if (type == TREE_TYPE (var))
  1072. {
  1073. DECL_ALIGN (field) = DECL_ALIGN (var);
  1074. DECL_USER_ALIGN (field) = DECL_USER_ALIGN (var);
  1075. TREE_THIS_VOLATILE (field) = TREE_THIS_VOLATILE (var);
  1076. }
  1077. else
  1078. DECL_ALIGN (field) = TYPE_ALIGN (type);
  1079. if ((mask & 3) == 3)
  1080. {
  1081. insert_field_into_struct (ctx->record_type, field);
  1082. if (ctx->srecord_type)
  1083. {
  1084. sfield = build_decl (DECL_SOURCE_LOCATION (var),
  1085. FIELD_DECL, DECL_NAME (var), type);
  1086. DECL_ABSTRACT_ORIGIN (sfield) = var;
  1087. DECL_ALIGN (sfield) = DECL_ALIGN (field);
  1088. DECL_USER_ALIGN (sfield) = DECL_USER_ALIGN (field);
  1089. TREE_THIS_VOLATILE (sfield) = TREE_THIS_VOLATILE (field);
  1090. insert_field_into_struct (ctx->srecord_type, sfield);
  1091. }
  1092. }
  1093. else
  1094. {
  1095. if (ctx->srecord_type == NULL_TREE)
  1096. {
  1097. tree t;
  1098. ctx->srecord_type = lang_hooks.types.make_type (RECORD_TYPE);
  1099. ctx->sfield_map = splay_tree_new (splay_tree_compare_pointers, 0, 0);
  1100. for (t = TYPE_FIELDS (ctx->record_type); t ; t = TREE_CHAIN (t))
  1101. {
  1102. sfield = build_decl (DECL_SOURCE_LOCATION (var),
  1103. FIELD_DECL, DECL_NAME (t), TREE_TYPE (t));
  1104. DECL_ABSTRACT_ORIGIN (sfield) = DECL_ABSTRACT_ORIGIN (t);
  1105. insert_field_into_struct (ctx->srecord_type, sfield);
  1106. splay_tree_insert (ctx->sfield_map,
  1107. (splay_tree_key) DECL_ABSTRACT_ORIGIN (t),
  1108. (splay_tree_value) sfield);
  1109. }
  1110. }
  1111. sfield = field;
  1112. insert_field_into_struct ((mask & 1) ? ctx->record_type
  1113. : ctx->srecord_type, field);
  1114. }
  1115. if (mask & 1)
  1116. splay_tree_insert (ctx->field_map, (splay_tree_key) var,
  1117. (splay_tree_value) field);
  1118. if ((mask & 2) && ctx->sfield_map)
  1119. splay_tree_insert (ctx->sfield_map, (splay_tree_key) var,
  1120. (splay_tree_value) sfield);
  1121. }
  1122. static tree
  1123. install_var_local (tree var, omp_context *ctx)
  1124. {
  1125. tree new_var = omp_copy_decl_1 (var, ctx);
  1126. insert_decl_map (&ctx->cb, var, new_var);
  1127. return new_var;
  1128. }
  1129. /* Adjust the replacement for DECL in CTX for the new context. This means
  1130. copying the DECL_VALUE_EXPR, and fixing up the type. */
  1131. static void
  1132. fixup_remapped_decl (tree decl, omp_context *ctx, bool private_debug)
  1133. {
  1134. tree new_decl, size;
  1135. new_decl = lookup_decl (decl, ctx);
  1136. TREE_TYPE (new_decl) = remap_type (TREE_TYPE (decl), &ctx->cb);
  1137. if ((!TREE_CONSTANT (DECL_SIZE (new_decl)) || private_debug)
  1138. && DECL_HAS_VALUE_EXPR_P (decl))
  1139. {
  1140. tree ve = DECL_VALUE_EXPR (decl);
  1141. walk_tree (&ve, copy_tree_body_r, &ctx->cb, NULL);
  1142. SET_DECL_VALUE_EXPR (new_decl, ve);
  1143. DECL_HAS_VALUE_EXPR_P (new_decl) = 1;
  1144. }
  1145. if (!TREE_CONSTANT (DECL_SIZE (new_decl)))
  1146. {
  1147. size = remap_decl (DECL_SIZE (decl), &ctx->cb);
  1148. if (size == error_mark_node)
  1149. size = TYPE_SIZE (TREE_TYPE (new_decl));
  1150. DECL_SIZE (new_decl) = size;
  1151. size = remap_decl (DECL_SIZE_UNIT (decl), &ctx->cb);
  1152. if (size == error_mark_node)
  1153. size = TYPE_SIZE_UNIT (TREE_TYPE (new_decl));
  1154. DECL_SIZE_UNIT (new_decl) = size;
  1155. }
  1156. }
  1157. /* The callback for remap_decl. Search all containing contexts for a
  1158. mapping of the variable; this avoids having to duplicate the splay
  1159. tree ahead of time. We know a mapping doesn't already exist in the
  1160. given context. Create new mappings to implement default semantics. */
  1161. static tree
  1162. omp_copy_decl (tree var, copy_body_data *cb)
  1163. {
  1164. omp_context *ctx = (omp_context *) cb;
  1165. tree new_var;
  1166. if (TREE_CODE (var) == LABEL_DECL)
  1167. {
  1168. new_var = create_artificial_label (DECL_SOURCE_LOCATION (var));
  1169. DECL_CONTEXT (new_var) = current_function_decl;
  1170. insert_decl_map (&ctx->cb, var, new_var);
  1171. return new_var;
  1172. }
  1173. while (!is_taskreg_ctx (ctx))
  1174. {
  1175. ctx = ctx->outer;
  1176. if (ctx == NULL)
  1177. return var;
  1178. new_var = maybe_lookup_decl (var, ctx);
  1179. if (new_var)
  1180. return new_var;
  1181. }
  1182. if (is_global_var (var) || decl_function_context (var) != ctx->cb.src_fn)
  1183. return var;
  1184. return error_mark_node;
  1185. }
  1186. /* Debugging dumps for parallel regions. */
  1187. void dump_omp_region (FILE *, struct omp_region *, int);
  1188. void debug_omp_region (struct omp_region *);
  1189. void debug_all_omp_regions (void);
  1190. /* Dump the parallel region tree rooted at REGION. */
  1191. void
  1192. dump_omp_region (FILE *file, struct omp_region *region, int indent)
  1193. {
  1194. fprintf (file, "%*sbb %d: %s\n", indent, "", region->entry->index,
  1195. gimple_code_name[region->type]);
  1196. if (region->inner)
  1197. dump_omp_region (file, region->inner, indent + 4);
  1198. if (region->cont)
  1199. {
  1200. fprintf (file, "%*sbb %d: GIMPLE_OMP_CONTINUE\n", indent, "",
  1201. region->cont->index);
  1202. }
  1203. if (region->exit)
  1204. fprintf (file, "%*sbb %d: GIMPLE_OMP_RETURN\n", indent, "",
  1205. region->exit->index);
  1206. else
  1207. fprintf (file, "%*s[no exit marker]\n", indent, "");
  1208. if (region->next)
  1209. dump_omp_region (file, region->next, indent);
  1210. }
  1211. DEBUG_FUNCTION void
  1212. debug_omp_region (struct omp_region *region)
  1213. {
  1214. dump_omp_region (stderr, region, 0);
  1215. }
  1216. DEBUG_FUNCTION void
  1217. debug_all_omp_regions (void)
  1218. {
  1219. dump_omp_region (stderr, root_omp_region, 0);
  1220. }
  1221. /* Create a new parallel region starting at STMT inside region PARENT. */
  1222. static struct omp_region *
  1223. new_omp_region (basic_block bb, enum gimple_code type,
  1224. struct omp_region *parent)
  1225. {
  1226. struct omp_region *region = XCNEW (struct omp_region);
  1227. region->outer = parent;
  1228. region->entry = bb;
  1229. region->type = type;
  1230. if (parent)
  1231. {
  1232. /* This is a nested region. Add it to the list of inner
  1233. regions in PARENT. */
  1234. region->next = parent->inner;
  1235. parent->inner = region;
  1236. }
  1237. else
  1238. {
  1239. /* This is a toplevel region. Add it to the list of toplevel
  1240. regions in ROOT_OMP_REGION. */
  1241. region->next = root_omp_region;
  1242. root_omp_region = region;
  1243. }
  1244. return region;
  1245. }
  1246. /* Release the memory associated with the region tree rooted at REGION. */
  1247. static void
  1248. free_omp_region_1 (struct omp_region *region)
  1249. {
  1250. struct omp_region *i, *n;
  1251. for (i = region->inner; i ; i = n)
  1252. {
  1253. n = i->next;
  1254. free_omp_region_1 (i);
  1255. }
  1256. free (region);
  1257. }
  1258. /* Release the memory for the entire omp region tree. */
  1259. void
  1260. free_omp_regions (void)
  1261. {
  1262. struct omp_region *r, *n;
  1263. for (r = root_omp_region; r ; r = n)
  1264. {
  1265. n = r->next;
  1266. free_omp_region_1 (r);
  1267. }
  1268. root_omp_region = NULL;
  1269. }
  1270. /* Create a new context, with OUTER_CTX being the surrounding context. */
  1271. static omp_context *
  1272. new_omp_context (gimple stmt, omp_context *outer_ctx)
  1273. {
  1274. omp_context *ctx = XCNEW (omp_context);
  1275. splay_tree_insert (all_contexts, (splay_tree_key) stmt,
  1276. (splay_tree_value) ctx);
  1277. ctx->stmt = stmt;
  1278. if (outer_ctx)
  1279. {
  1280. ctx->outer = outer_ctx;
  1281. ctx->cb = outer_ctx->cb;
  1282. ctx->cb.block = NULL;
  1283. ctx->depth = outer_ctx->depth + 1;
  1284. ctx->reduction_map = outer_ctx->reduction_map;
  1285. }
  1286. else
  1287. {
  1288. ctx->cb.src_fn = current_function_decl;
  1289. ctx->cb.dst_fn = current_function_decl;
  1290. ctx->cb.src_node = cgraph_node::get (current_function_decl);
  1291. gcc_checking_assert (ctx->cb.src_node);
  1292. ctx->cb.dst_node = ctx->cb.src_node;
  1293. ctx->cb.src_cfun = cfun;
  1294. ctx->cb.copy_decl = omp_copy_decl;
  1295. ctx->cb.eh_lp_nr = 0;
  1296. ctx->cb.transform_call_graph_edges = CB_CGE_MOVE;
  1297. ctx->depth = 1;
  1298. }
  1299. ctx->cb.decl_map = new hash_map<tree, tree>;
  1300. return ctx;
  1301. }
  1302. static gimple_seq maybe_catch_exception (gimple_seq);
  1303. /* Finalize task copyfn. */
  1304. static void
  1305. finalize_task_copyfn (gomp_task *task_stmt)
  1306. {
  1307. struct function *child_cfun;
  1308. tree child_fn;
  1309. gimple_seq seq = NULL, new_seq;
  1310. gbind *bind;
  1311. child_fn = gimple_omp_task_copy_fn (task_stmt);
  1312. if (child_fn == NULL_TREE)
  1313. return;
  1314. child_cfun = DECL_STRUCT_FUNCTION (child_fn);
  1315. DECL_STRUCT_FUNCTION (child_fn)->curr_properties = cfun->curr_properties;
  1316. push_cfun (child_cfun);
  1317. bind = gimplify_body (child_fn, false);
  1318. gimple_seq_add_stmt (&seq, bind);
  1319. new_seq = maybe_catch_exception (seq);
  1320. if (new_seq != seq)
  1321. {
  1322. bind = gimple_build_bind (NULL, new_seq, NULL);
  1323. seq = NULL;
  1324. gimple_seq_add_stmt (&seq, bind);
  1325. }
  1326. gimple_set_body (child_fn, seq);
  1327. pop_cfun ();
  1328. /* Inform the callgraph about the new function. */
  1329. cgraph_node::add_new_function (child_fn, false);
  1330. cgraph_node::get (child_fn)->parallelized_function = 1;
  1331. }
  1332. /* Destroy a omp_context data structures. Called through the splay tree
  1333. value delete callback. */
  1334. static void
  1335. delete_omp_context (splay_tree_value value)
  1336. {
  1337. omp_context *ctx = (omp_context *) value;
  1338. delete ctx->cb.decl_map;
  1339. if (ctx->field_map)
  1340. splay_tree_delete (ctx->field_map);
  1341. if (ctx->sfield_map)
  1342. splay_tree_delete (ctx->sfield_map);
  1343. /* Reduction map is copied to nested contexts, so only delete it in the
  1344. owner. */
  1345. if (ctx->reduction_map
  1346. && gimple_code (ctx->stmt) == GIMPLE_OMP_TARGET
  1347. && is_gimple_omp_offloaded (ctx->stmt)
  1348. && is_gimple_omp_oacc (ctx->stmt))
  1349. splay_tree_delete (ctx->reduction_map);
  1350. /* We hijacked DECL_ABSTRACT_ORIGIN earlier. We need to clear it before
  1351. it produces corrupt debug information. */
  1352. if (ctx->record_type)
  1353. {
  1354. tree t;
  1355. for (t = TYPE_FIELDS (ctx->record_type); t ; t = DECL_CHAIN (t))
  1356. DECL_ABSTRACT_ORIGIN (t) = NULL;
  1357. }
  1358. if (ctx->srecord_type)
  1359. {
  1360. tree t;
  1361. for (t = TYPE_FIELDS (ctx->srecord_type); t ; t = DECL_CHAIN (t))
  1362. DECL_ABSTRACT_ORIGIN (t) = NULL;
  1363. }
  1364. if (is_task_ctx (ctx))
  1365. finalize_task_copyfn (as_a <gomp_task *> (ctx->stmt));
  1366. XDELETE (ctx);
  1367. }
  1368. /* Fix up RECEIVER_DECL with a type that has been remapped to the child
  1369. context. */
  1370. static void
  1371. fixup_child_record_type (omp_context *ctx)
  1372. {
  1373. tree f, type = ctx->record_type;
  1374. /* ??? It isn't sufficient to just call remap_type here, because
  1375. variably_modified_type_p doesn't work the way we expect for
  1376. record types. Testing each field for whether it needs remapping
  1377. and creating a new record by hand works, however. */
  1378. for (f = TYPE_FIELDS (type); f ; f = DECL_CHAIN (f))
  1379. if (variably_modified_type_p (TREE_TYPE (f), ctx->cb.src_fn))
  1380. break;
  1381. if (f)
  1382. {
  1383. tree name, new_fields = NULL;
  1384. type = lang_hooks.types.make_type (RECORD_TYPE);
  1385. name = DECL_NAME (TYPE_NAME (ctx->record_type));
  1386. name = build_decl (DECL_SOURCE_LOCATION (ctx->receiver_decl),
  1387. TYPE_DECL, name, type);
  1388. TYPE_NAME (type) = name;
  1389. for (f = TYPE_FIELDS (ctx->record_type); f ; f = DECL_CHAIN (f))
  1390. {
  1391. tree new_f = copy_node (f);
  1392. DECL_CONTEXT (new_f) = type;
  1393. TREE_TYPE (new_f) = remap_type (TREE_TYPE (f), &ctx->cb);
  1394. DECL_CHAIN (new_f) = new_fields;
  1395. walk_tree (&DECL_SIZE (new_f), copy_tree_body_r, &ctx->cb, NULL);
  1396. walk_tree (&DECL_SIZE_UNIT (new_f), copy_tree_body_r,
  1397. &ctx->cb, NULL);
  1398. walk_tree (&DECL_FIELD_OFFSET (new_f), copy_tree_body_r,
  1399. &ctx->cb, NULL);
  1400. new_fields = new_f;
  1401. /* Arrange to be able to look up the receiver field
  1402. given the sender field. */
  1403. splay_tree_insert (ctx->field_map, (splay_tree_key) f,
  1404. (splay_tree_value) new_f);
  1405. }
  1406. TYPE_FIELDS (type) = nreverse (new_fields);
  1407. layout_type (type);
  1408. }
  1409. TREE_TYPE (ctx->receiver_decl)
  1410. = build_qualified_type (build_reference_type (type), TYPE_QUAL_RESTRICT);
  1411. }
  1412. /* Instantiate decls as necessary in CTX to satisfy the data sharing
  1413. specified by CLAUSES. */
  1414. static void
  1415. scan_sharing_clauses (tree clauses, omp_context *ctx)
  1416. {
  1417. tree c, decl;
  1418. bool scan_array_reductions = false;
  1419. for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
  1420. {
  1421. bool by_ref;
  1422. switch (OMP_CLAUSE_CODE (c))
  1423. {
  1424. case OMP_CLAUSE_PRIVATE:
  1425. decl = OMP_CLAUSE_DECL (c);
  1426. if (OMP_CLAUSE_PRIVATE_OUTER_REF (c))
  1427. goto do_private;
  1428. else if (!is_variable_sized (decl))
  1429. install_var_local (decl, ctx);
  1430. break;
  1431. case OMP_CLAUSE_SHARED:
  1432. decl = OMP_CLAUSE_DECL (c);
  1433. /* Ignore shared directives in teams construct. */
  1434. if (gimple_code (ctx->stmt) == GIMPLE_OMP_TEAMS)
  1435. {
  1436. /* Global variables don't need to be copied,
  1437. the receiver side will use them directly. */
  1438. tree odecl = maybe_lookup_decl_in_outer_ctx (decl, ctx);
  1439. if (is_global_var (odecl))
  1440. break;
  1441. insert_decl_map (&ctx->cb, decl, odecl);
  1442. break;
  1443. }
  1444. gcc_assert (is_taskreg_ctx (ctx));
  1445. gcc_assert (!COMPLETE_TYPE_P (TREE_TYPE (decl))
  1446. || !is_variable_sized (decl));
  1447. /* Global variables don't need to be copied,
  1448. the receiver side will use them directly. */
  1449. if (is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx)))
  1450. break;
  1451. by_ref = use_pointer_for_field (decl, ctx);
  1452. if (! TREE_READONLY (decl)
  1453. || TREE_ADDRESSABLE (decl)
  1454. || by_ref
  1455. || is_reference (decl))
  1456. {
  1457. install_var_field (decl, by_ref, 3, ctx);
  1458. install_var_local (decl, ctx);
  1459. break;
  1460. }
  1461. /* We don't need to copy const scalar vars back. */
  1462. OMP_CLAUSE_SET_CODE (c, OMP_CLAUSE_FIRSTPRIVATE);
  1463. goto do_private;
  1464. case OMP_CLAUSE_LASTPRIVATE:
  1465. /* Let the corresponding firstprivate clause create
  1466. the variable. */
  1467. if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
  1468. break;
  1469. /* FALLTHRU */
  1470. case OMP_CLAUSE_FIRSTPRIVATE:
  1471. if (is_gimple_omp_oacc (ctx->stmt))
  1472. {
  1473. sorry ("clause not supported yet");
  1474. break;
  1475. }
  1476. /* FALLTHRU */
  1477. case OMP_CLAUSE_REDUCTION:
  1478. case OMP_CLAUSE_LINEAR:
  1479. decl = OMP_CLAUSE_DECL (c);
  1480. do_private:
  1481. if (is_variable_sized (decl))
  1482. {
  1483. if (is_task_ctx (ctx))
  1484. install_var_field (decl, false, 1, ctx);
  1485. break;
  1486. }
  1487. else if (is_taskreg_ctx (ctx))
  1488. {
  1489. bool global
  1490. = is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx));
  1491. by_ref = use_pointer_for_field (decl, NULL);
  1492. if (is_task_ctx (ctx)
  1493. && (global || by_ref || is_reference (decl)))
  1494. {
  1495. install_var_field (decl, false, 1, ctx);
  1496. if (!global)
  1497. install_var_field (decl, by_ref, 2, ctx);
  1498. }
  1499. else if (!global)
  1500. install_var_field (decl, by_ref, 3, ctx);
  1501. }
  1502. install_var_local (decl, ctx);
  1503. if (is_gimple_omp_oacc (ctx->stmt)
  1504. && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION)
  1505. {
  1506. /* Create a decl for the reduction array. */
  1507. tree var = OMP_CLAUSE_DECL (c);
  1508. tree type = get_base_type (var);
  1509. tree ptype = build_pointer_type (type);
  1510. tree array = create_tmp_var (ptype,
  1511. oacc_get_reduction_array_id (var));
  1512. omp_context *c = (ctx->field_map ? ctx : ctx->outer);
  1513. install_var_field (array, true, 3, c);
  1514. install_var_local (array, c);
  1515. /* Insert it into the current context. */
  1516. splay_tree_insert (ctx->reduction_map, (splay_tree_key)
  1517. oacc_get_reduction_array_id (var),
  1518. (splay_tree_value) array);
  1519. splay_tree_insert (ctx->reduction_map,
  1520. (splay_tree_key) array,
  1521. (splay_tree_value) array);
  1522. }
  1523. break;
  1524. case OMP_CLAUSE__LOOPTEMP_:
  1525. gcc_assert (is_parallel_ctx (ctx));
  1526. decl = OMP_CLAUSE_DECL (c);
  1527. install_var_field (decl, false, 3, ctx);
  1528. install_var_local (decl, ctx);
  1529. break;
  1530. case OMP_CLAUSE_COPYPRIVATE:
  1531. case OMP_CLAUSE_COPYIN:
  1532. decl = OMP_CLAUSE_DECL (c);
  1533. by_ref = use_pointer_for_field (decl, NULL);
  1534. install_var_field (decl, by_ref, 3, ctx);
  1535. break;
  1536. case OMP_CLAUSE_DEFAULT:
  1537. ctx->default_kind = OMP_CLAUSE_DEFAULT_KIND (c);
  1538. break;
  1539. case OMP_CLAUSE_FINAL:
  1540. case OMP_CLAUSE_IF:
  1541. case OMP_CLAUSE_NUM_THREADS:
  1542. case OMP_CLAUSE_NUM_TEAMS:
  1543. case OMP_CLAUSE_THREAD_LIMIT:
  1544. case OMP_CLAUSE_DEVICE:
  1545. case OMP_CLAUSE_SCHEDULE:
  1546. case OMP_CLAUSE_DIST_SCHEDULE:
  1547. case OMP_CLAUSE_DEPEND:
  1548. case OMP_CLAUSE__CILK_FOR_COUNT_:
  1549. case OMP_CLAUSE_NUM_GANGS:
  1550. case OMP_CLAUSE_NUM_WORKERS:
  1551. case OMP_CLAUSE_VECTOR_LENGTH:
  1552. if (ctx->outer)
  1553. scan_omp_op (&OMP_CLAUSE_OPERAND (c, 0), ctx->outer);
  1554. break;
  1555. case OMP_CLAUSE_TO:
  1556. case OMP_CLAUSE_FROM:
  1557. case OMP_CLAUSE_MAP:
  1558. if (ctx->outer)
  1559. scan_omp_op (&OMP_CLAUSE_SIZE (c), ctx->outer);
  1560. decl = OMP_CLAUSE_DECL (c);
  1561. /* Global variables with "omp declare target" attribute
  1562. don't need to be copied, the receiver side will use them
  1563. directly. */
  1564. if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
  1565. && DECL_P (decl)
  1566. && is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx))
  1567. && varpool_node::get_create (decl)->offloadable)
  1568. break;
  1569. if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
  1570. && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POINTER)
  1571. {
  1572. /* Ignore GOMP_MAP_POINTER kind for arrays in regions that are
  1573. not offloaded; there is nothing to map for those. */
  1574. if (!is_gimple_omp_offloaded (ctx->stmt)
  1575. && !POINTER_TYPE_P (TREE_TYPE (decl))
  1576. && !OMP_CLAUSE_MAP_ZERO_BIAS_ARRAY_SECTION (c))
  1577. break;
  1578. }
  1579. if (DECL_P (decl))
  1580. {
  1581. if (DECL_SIZE (decl)
  1582. && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
  1583. {
  1584. tree decl2 = DECL_VALUE_EXPR (decl);
  1585. gcc_assert (TREE_CODE (decl2) == INDIRECT_REF);
  1586. decl2 = TREE_OPERAND (decl2, 0);
  1587. gcc_assert (DECL_P (decl2));
  1588. install_var_field (decl2, true, 3, ctx);
  1589. install_var_local (decl2, ctx);
  1590. install_var_local (decl, ctx);
  1591. }
  1592. else
  1593. {
  1594. if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
  1595. && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POINTER
  1596. && !OMP_CLAUSE_MAP_ZERO_BIAS_ARRAY_SECTION (c)
  1597. && TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
  1598. install_var_field (decl, true, 7, ctx);
  1599. else
  1600. install_var_field (decl, true, 3, ctx);
  1601. if (is_gimple_omp_offloaded (ctx->stmt))
  1602. install_var_local (decl, ctx);
  1603. }
  1604. }
  1605. else
  1606. {
  1607. tree base = get_base_address (decl);
  1608. tree nc = OMP_CLAUSE_CHAIN (c);
  1609. if (DECL_P (base)
  1610. && nc != NULL_TREE
  1611. && OMP_CLAUSE_CODE (nc) == OMP_CLAUSE_MAP
  1612. && OMP_CLAUSE_DECL (nc) == base
  1613. && OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_POINTER
  1614. && integer_zerop (OMP_CLAUSE_SIZE (nc)))
  1615. {
  1616. OMP_CLAUSE_MAP_ZERO_BIAS_ARRAY_SECTION (c) = 1;
  1617. OMP_CLAUSE_MAP_ZERO_BIAS_ARRAY_SECTION (nc) = 1;
  1618. }
  1619. else
  1620. {
  1621. if (ctx->outer)
  1622. {
  1623. scan_omp_op (&OMP_CLAUSE_DECL (c), ctx->outer);
  1624. decl = OMP_CLAUSE_DECL (c);
  1625. }
  1626. gcc_assert (!splay_tree_lookup (ctx->field_map,
  1627. (splay_tree_key) decl));
  1628. tree field
  1629. = build_decl (OMP_CLAUSE_LOCATION (c),
  1630. FIELD_DECL, NULL_TREE, ptr_type_node);
  1631. DECL_ALIGN (field) = TYPE_ALIGN (ptr_type_node);
  1632. insert_field_into_struct (ctx->record_type, field);
  1633. splay_tree_insert (ctx->field_map, (splay_tree_key) decl,
  1634. (splay_tree_value) field);
  1635. }
  1636. }
  1637. break;
  1638. case OMP_CLAUSE_NOWAIT:
  1639. case OMP_CLAUSE_ORDERED:
  1640. case OMP_CLAUSE_COLLAPSE:
  1641. case OMP_CLAUSE_UNTIED:
  1642. case OMP_CLAUSE_MERGEABLE:
  1643. case OMP_CLAUSE_PROC_BIND:
  1644. case OMP_CLAUSE_SAFELEN:
  1645. case OMP_CLAUSE_ASYNC:
  1646. case OMP_CLAUSE_WAIT:
  1647. case OMP_CLAUSE_GANG:
  1648. case OMP_CLAUSE_WORKER:
  1649. case OMP_CLAUSE_VECTOR:
  1650. break;
  1651. case OMP_CLAUSE_ALIGNED:
  1652. decl = OMP_CLAUSE_DECL (c);
  1653. if (is_global_var (decl)
  1654. && TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
  1655. install_var_local (decl, ctx);
  1656. break;
  1657. case OMP_CLAUSE_DEVICE_RESIDENT:
  1658. case OMP_CLAUSE_USE_DEVICE:
  1659. case OMP_CLAUSE__CACHE_:
  1660. case OMP_CLAUSE_INDEPENDENT:
  1661. case OMP_CLAUSE_AUTO:
  1662. case OMP_CLAUSE_SEQ:
  1663. sorry ("Clause not supported yet");
  1664. break;
  1665. default:
  1666. gcc_unreachable ();
  1667. }
  1668. }
  1669. for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
  1670. {
  1671. switch (OMP_CLAUSE_CODE (c))
  1672. {
  1673. case OMP_CLAUSE_LASTPRIVATE:
  1674. /* Let the corresponding firstprivate clause create
  1675. the variable. */
  1676. if (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c))
  1677. scan_array_reductions = true;
  1678. if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
  1679. break;
  1680. /* FALLTHRU */
  1681. case OMP_CLAUSE_FIRSTPRIVATE:
  1682. if (is_gimple_omp_oacc (ctx->stmt))
  1683. {
  1684. sorry ("clause not supported yet");
  1685. break;
  1686. }
  1687. /* FALLTHRU */
  1688. case OMP_CLAUSE_PRIVATE:
  1689. case OMP_CLAUSE_REDUCTION:
  1690. case OMP_CLAUSE_LINEAR:
  1691. decl = OMP_CLAUSE_DECL (c);
  1692. if (is_variable_sized (decl))
  1693. install_var_local (decl, ctx);
  1694. fixup_remapped_decl (decl, ctx,
  1695. OMP_CLAUSE_CODE (c) == OMP_CLAUSE_PRIVATE
  1696. && OMP_CLAUSE_PRIVATE_DEBUG (c));
  1697. if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
  1698. && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
  1699. scan_array_reductions = true;
  1700. else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
  1701. && OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c))
  1702. scan_array_reductions = true;
  1703. break;
  1704. case OMP_CLAUSE_SHARED:
  1705. /* Ignore shared directives in teams construct. */
  1706. if (gimple_code (ctx->stmt) == GIMPLE_OMP_TEAMS)
  1707. break;
  1708. decl = OMP_CLAUSE_DECL (c);
  1709. if (! is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx)))
  1710. fixup_remapped_decl (decl, ctx, false);
  1711. break;
  1712. case OMP_CLAUSE_MAP:
  1713. if (!is_gimple_omp_offloaded (ctx->stmt))
  1714. break;
  1715. decl = OMP_CLAUSE_DECL (c);
  1716. if (DECL_P (decl)
  1717. && is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx))
  1718. && varpool_node::get_create (decl)->offloadable)
  1719. break;
  1720. if (DECL_P (decl))
  1721. {
  1722. if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POINTER
  1723. && TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE
  1724. && !COMPLETE_TYPE_P (TREE_TYPE (decl)))
  1725. {
  1726. tree new_decl = lookup_decl (decl, ctx);
  1727. TREE_TYPE (new_decl)
  1728. = remap_type (TREE_TYPE (decl), &ctx->cb);
  1729. }
  1730. else if (DECL_SIZE (decl)
  1731. && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
  1732. {
  1733. tree decl2 = DECL_VALUE_EXPR (decl);
  1734. gcc_assert (TREE_CODE (decl2) == INDIRECT_REF);
  1735. decl2 = TREE_OPERAND (decl2, 0);
  1736. gcc_assert (DECL_P (decl2));
  1737. fixup_remapped_decl (decl2, ctx, false);
  1738. fixup_remapped_decl (decl, ctx, true);
  1739. }
  1740. else
  1741. fixup_remapped_decl (decl, ctx, false);
  1742. }
  1743. break;
  1744. case OMP_CLAUSE_COPYPRIVATE:
  1745. case OMP_CLAUSE_COPYIN:
  1746. case OMP_CLAUSE_DEFAULT:
  1747. case OMP_CLAUSE_IF:
  1748. case OMP_CLAUSE_NUM_THREADS:
  1749. case OMP_CLAUSE_NUM_TEAMS:
  1750. case OMP_CLAUSE_THREAD_LIMIT:
  1751. case OMP_CLAUSE_DEVICE:
  1752. case OMP_CLAUSE_SCHEDULE:
  1753. case OMP_CLAUSE_DIST_SCHEDULE:
  1754. case OMP_CLAUSE_NOWAIT:
  1755. case OMP_CLAUSE_ORDERED:
  1756. case OMP_CLAUSE_COLLAPSE:
  1757. case OMP_CLAUSE_UNTIED:
  1758. case OMP_CLAUSE_FINAL:
  1759. case OMP_CLAUSE_MERGEABLE:
  1760. case OMP_CLAUSE_PROC_BIND:
  1761. case OMP_CLAUSE_SAFELEN:
  1762. case OMP_CLAUSE_ALIGNED:
  1763. case OMP_CLAUSE_DEPEND:
  1764. case OMP_CLAUSE__LOOPTEMP_:
  1765. case OMP_CLAUSE_TO:
  1766. case OMP_CLAUSE_FROM:
  1767. case OMP_CLAUSE__CILK_FOR_COUNT_:
  1768. case OMP_CLAUSE_ASYNC:
  1769. case OMP_CLAUSE_WAIT:
  1770. case OMP_CLAUSE_NUM_GANGS:
  1771. case OMP_CLAUSE_NUM_WORKERS:
  1772. case OMP_CLAUSE_VECTOR_LENGTH:
  1773. case OMP_CLAUSE_GANG:
  1774. case OMP_CLAUSE_WORKER:
  1775. case OMP_CLAUSE_VECTOR:
  1776. break;
  1777. case OMP_CLAUSE_DEVICE_RESIDENT:
  1778. case OMP_CLAUSE_USE_DEVICE:
  1779. case OMP_CLAUSE__CACHE_:
  1780. case OMP_CLAUSE_INDEPENDENT:
  1781. case OMP_CLAUSE_AUTO:
  1782. case OMP_CLAUSE_SEQ:
  1783. sorry ("Clause not supported yet");
  1784. break;
  1785. default:
  1786. gcc_unreachable ();
  1787. }
  1788. }
  1789. gcc_checking_assert (!scan_array_reductions
  1790. || !is_gimple_omp_oacc (ctx->stmt));
  1791. if (scan_array_reductions)
  1792. for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
  1793. if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
  1794. && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
  1795. {
  1796. scan_omp (&OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c), ctx);
  1797. scan_omp (&OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c), ctx);
  1798. }
  1799. else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
  1800. && OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c))
  1801. scan_omp (&OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c), ctx);
  1802. else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
  1803. && OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c))
  1804. scan_omp (&OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c), ctx);
  1805. }
  1806. /* Create a new name for omp child function. Returns an identifier. If
  1807. IS_CILK_FOR is true then the suffix for the child function is
  1808. "_cilk_for_fn." */
  1809. static tree
  1810. create_omp_child_function_name (bool task_copy, bool is_cilk_for)
  1811. {
  1812. if (is_cilk_for)
  1813. return clone_function_name (current_function_decl, "_cilk_for_fn");
  1814. return clone_function_name (current_function_decl,
  1815. task_copy ? "_omp_cpyfn" : "_omp_fn");
  1816. }
  1817. /* Returns the type of the induction variable for the child function for
  1818. _Cilk_for and the types for _high and _low variables based on TYPE. */
  1819. static tree
  1820. cilk_for_check_loop_diff_type (tree type)
  1821. {
  1822. if (TYPE_PRECISION (type) <= TYPE_PRECISION (uint32_type_node))
  1823. {
  1824. if (TYPE_UNSIGNED (type))
  1825. return uint32_type_node;
  1826. else
  1827. return integer_type_node;
  1828. }
  1829. else
  1830. {
  1831. if (TYPE_UNSIGNED (type))
  1832. return uint64_type_node;
  1833. else
  1834. return long_long_integer_type_node;
  1835. }
  1836. }
  1837. /* Build a decl for the omp child function. It'll not contain a body
  1838. yet, just the bare decl. */
  1839. static void
  1840. create_omp_child_function (omp_context *ctx, bool task_copy)
  1841. {
  1842. tree decl, type, name, t;
  1843. tree cilk_for_count
  1844. = (flag_cilkplus && gimple_code (ctx->stmt) == GIMPLE_OMP_PARALLEL)
  1845. ? find_omp_clause (gimple_omp_parallel_clauses (ctx->stmt),
  1846. OMP_CLAUSE__CILK_FOR_COUNT_) : NULL_TREE;
  1847. tree cilk_var_type = NULL_TREE;
  1848. name = create_omp_child_function_name (task_copy,
  1849. cilk_for_count != NULL_TREE);
  1850. if (task_copy)
  1851. type = build_function_type_list (void_type_node, ptr_type_node,
  1852. ptr_type_node, NULL_TREE);
  1853. else if (cilk_for_count)
  1854. {
  1855. type = TREE_TYPE (OMP_CLAUSE_OPERAND (cilk_for_count, 0));
  1856. cilk_var_type = cilk_for_check_loop_diff_type (type);
  1857. type = build_function_type_list (void_type_node, ptr_type_node,
  1858. cilk_var_type, cilk_var_type, NULL_TREE);
  1859. }
  1860. else
  1861. type = build_function_type_list (void_type_node, ptr_type_node, NULL_TREE);
  1862. decl = build_decl (gimple_location (ctx->stmt), FUNCTION_DECL, name, type);
  1863. gcc_checking_assert (!is_gimple_omp_oacc (ctx->stmt)
  1864. || !task_copy);
  1865. if (!task_copy)
  1866. ctx->cb.dst_fn = decl;
  1867. else
  1868. gimple_omp_task_set_copy_fn (ctx->stmt, decl);
  1869. TREE_STATIC (decl) = 1;
  1870. TREE_USED (decl) = 1;
  1871. DECL_ARTIFICIAL (decl) = 1;
  1872. DECL_IGNORED_P (decl) = 0;
  1873. TREE_PUBLIC (decl) = 0;
  1874. DECL_UNINLINABLE (decl) = 1;
  1875. DECL_EXTERNAL (decl) = 0;
  1876. DECL_CONTEXT (decl) = NULL_TREE;
  1877. DECL_INITIAL (decl) = make_node (BLOCK);
  1878. if (cgraph_node::get (current_function_decl)->offloadable)
  1879. cgraph_node::get_create (decl)->offloadable = 1;
  1880. else
  1881. {
  1882. omp_context *octx;
  1883. for (octx = ctx; octx; octx = octx->outer)
  1884. if (is_gimple_omp_offloaded (octx->stmt))
  1885. {
  1886. cgraph_node::get_create (decl)->offloadable = 1;
  1887. #ifdef ENABLE_OFFLOADING
  1888. g->have_offload = true;
  1889. #endif
  1890. break;
  1891. }
  1892. }
  1893. if (cgraph_node::get_create (decl)->offloadable
  1894. && !lookup_attribute ("omp declare target",
  1895. DECL_ATTRIBUTES (current_function_decl)))
  1896. DECL_ATTRIBUTES (decl)
  1897. = tree_cons (get_identifier ("omp target entrypoint"),
  1898. NULL_TREE, DECL_ATTRIBUTES (decl));
  1899. t = build_decl (DECL_SOURCE_LOCATION (decl),
  1900. RESULT_DECL, NULL_TREE, void_type_node);
  1901. DECL_ARTIFICIAL (t) = 1;
  1902. DECL_IGNORED_P (t) = 1;
  1903. DECL_CONTEXT (t) = decl;
  1904. DECL_RESULT (decl) = t;
  1905. /* _Cilk_for's child function requires two extra parameters called
  1906. __low and __high that are set the by Cilk runtime when it calls this
  1907. function. */
  1908. if (cilk_for_count)
  1909. {
  1910. t = build_decl (DECL_SOURCE_LOCATION (decl),
  1911. PARM_DECL, get_identifier ("__high"), cilk_var_type);
  1912. DECL_ARTIFICIAL (t) = 1;
  1913. DECL_NAMELESS (t) = 1;
  1914. DECL_ARG_TYPE (t) = ptr_type_node;
  1915. DECL_CONTEXT (t) = current_function_decl;
  1916. TREE_USED (t) = 1;
  1917. DECL_CHAIN (t) = DECL_ARGUMENTS (decl);
  1918. DECL_ARGUMENTS (decl) = t;
  1919. t = build_decl (DECL_SOURCE_LOCATION (decl),
  1920. PARM_DECL, get_identifier ("__low"), cilk_var_type);
  1921. DECL_ARTIFICIAL (t) = 1;
  1922. DECL_NAMELESS (t) = 1;
  1923. DECL_ARG_TYPE (t) = ptr_type_node;
  1924. DECL_CONTEXT (t) = current_function_decl;
  1925. TREE_USED (t) = 1;
  1926. DECL_CHAIN (t) = DECL_ARGUMENTS (decl);
  1927. DECL_ARGUMENTS (decl) = t;
  1928. }
  1929. tree data_name = get_identifier (".omp_data_i");
  1930. t = build_decl (DECL_SOURCE_LOCATION (decl), PARM_DECL, data_name,
  1931. ptr_type_node);
  1932. DECL_ARTIFICIAL (t) = 1;
  1933. DECL_NAMELESS (t) = 1;
  1934. DECL_ARG_TYPE (t) = ptr_type_node;
  1935. DECL_CONTEXT (t) = current_function_decl;
  1936. TREE_USED (t) = 1;
  1937. if (cilk_for_count)
  1938. DECL_CHAIN (t) = DECL_ARGUMENTS (decl);
  1939. DECL_ARGUMENTS (decl) = t;
  1940. if (!task_copy)
  1941. ctx->receiver_decl = t;
  1942. else
  1943. {
  1944. t = build_decl (DECL_SOURCE_LOCATION (decl),
  1945. PARM_DECL, get_identifier (".omp_data_o"),
  1946. ptr_type_node);
  1947. DECL_ARTIFICIAL (t) = 1;
  1948. DECL_NAMELESS (t) = 1;
  1949. DECL_ARG_TYPE (t) = ptr_type_node;
  1950. DECL_CONTEXT (t) = current_function_decl;
  1951. TREE_USED (t) = 1;
  1952. TREE_ADDRESSABLE (t) = 1;
  1953. DECL_CHAIN (t) = DECL_ARGUMENTS (decl);
  1954. DECL_ARGUMENTS (decl) = t;
  1955. }
  1956. /* Allocate memory for the function structure. The call to
  1957. allocate_struct_function clobbers CFUN, so we need to restore
  1958. it afterward. */
  1959. push_struct_function (decl);
  1960. cfun->function_end_locus = gimple_location (ctx->stmt);
  1961. pop_cfun ();
  1962. }
  1963. /* Callback for walk_gimple_seq. Check if combined parallel
  1964. contains gimple_omp_for_combined_into_p OMP_FOR. */
  1965. static tree
  1966. find_combined_for (gimple_stmt_iterator *gsi_p,
  1967. bool *handled_ops_p,
  1968. struct walk_stmt_info *wi)
  1969. {
  1970. gimple stmt = gsi_stmt (*gsi_p);
  1971. *handled_ops_p = true;
  1972. switch (gimple_code (stmt))
  1973. {
  1974. WALK_SUBSTMTS;
  1975. case GIMPLE_OMP_FOR:
  1976. if (gimple_omp_for_combined_into_p (stmt)
  1977. && gimple_omp_for_kind (stmt) == GF_OMP_FOR_KIND_FOR)
  1978. {
  1979. wi->info = stmt;
  1980. return integer_zero_node;
  1981. }
  1982. break;
  1983. default:
  1984. break;
  1985. }
  1986. return NULL;
  1987. }
  1988. /* Scan an OpenMP parallel directive. */
  1989. static void
  1990. scan_omp_parallel (gimple_stmt_iterator *gsi, omp_context *outer_ctx)
  1991. {
  1992. omp_context *ctx;
  1993. tree name;
  1994. gomp_parallel *stmt = as_a <gomp_parallel *> (gsi_stmt (*gsi));
  1995. /* Ignore parallel directives with empty bodies, unless there
  1996. are copyin clauses. */
  1997. if (optimize > 0
  1998. && empty_body_p (gimple_omp_body (stmt))
  1999. && find_omp_clause (gimple_omp_parallel_clauses (stmt),
  2000. OMP_CLAUSE_COPYIN) == NULL)
  2001. {
  2002. gsi_replace (gsi, gimple_build_nop (), false);
  2003. return;
  2004. }
  2005. if (gimple_omp_parallel_combined_p (stmt))
  2006. {
  2007. struct walk_stmt_info wi;
  2008. memset (&wi, 0, sizeof (wi));
  2009. wi.val_only = true;
  2010. walk_gimple_seq (gimple_omp_body (stmt),
  2011. find_combined_for, NULL, &wi);
  2012. if (wi.info)
  2013. {
  2014. gomp_for *for_stmt = as_a <gomp_for *> ((gimple) wi.info);
  2015. struct omp_for_data fd;
  2016. extract_omp_for_data (for_stmt, &fd, NULL);
  2017. /* We need two temporaries with fd.loop.v type (istart/iend)
  2018. and then (fd.collapse - 1) temporaries with the same
  2019. type for count2 ... countN-1 vars if not constant. */
  2020. size_t count = 2, i;
  2021. tree type = fd.iter_type;
  2022. if (fd.collapse > 1
  2023. && TREE_CODE (fd.loop.n2) != INTEGER_CST)
  2024. count += fd.collapse - 1;
  2025. for (i = 0; i < count; i++)
  2026. {
  2027. tree temp = create_tmp_var (type);
  2028. tree c = build_omp_clause (UNKNOWN_LOCATION,
  2029. OMP_CLAUSE__LOOPTEMP_);
  2030. insert_decl_map (&outer_ctx->cb, temp, temp);
  2031. OMP_CLAUSE_DECL (c) = temp;
  2032. OMP_CLAUSE_CHAIN (c) = gimple_omp_parallel_clauses (stmt);
  2033. gimple_omp_parallel_set_clauses (stmt, c);
  2034. }
  2035. }
  2036. }
  2037. ctx = new_omp_context (stmt, outer_ctx);
  2038. taskreg_contexts.safe_push (ctx);
  2039. if (taskreg_nesting_level > 1)
  2040. ctx->is_nested = true;
  2041. ctx->field_map = splay_tree_new (splay_tree_compare_pointers, 0, 0);
  2042. ctx->default_kind = OMP_CLAUSE_DEFAULT_SHARED;
  2043. ctx->record_type = lang_hooks.types.make_type (RECORD_TYPE);
  2044. name = create_tmp_var_name (".omp_data_s");
  2045. name = build_decl (gimple_location (stmt),
  2046. TYPE_DECL, name, ctx->record_type);
  2047. DECL_ARTIFICIAL (name) = 1;
  2048. DECL_NAMELESS (name) = 1;
  2049. TYPE_NAME (ctx->record_type) = name;
  2050. TYPE_ARTIFICIAL (ctx->record_type) = 1;
  2051. create_omp_child_function (ctx, false);
  2052. gimple_omp_parallel_set_child_fn (stmt, ctx->cb.dst_fn);
  2053. scan_sharing_clauses (gimple_omp_parallel_clauses (stmt), ctx);
  2054. scan_omp (gimple_omp_body_ptr (stmt), ctx);
  2055. if (TYPE_FIELDS (ctx->record_type) == NULL)
  2056. ctx->record_type = ctx->receiver_decl = NULL;
  2057. }
  2058. /* Scan an OpenMP task directive. */
  2059. static void
  2060. scan_omp_task (gimple_stmt_iterator *gsi, omp_context *outer_ctx)
  2061. {
  2062. omp_context *ctx;
  2063. tree name, t;
  2064. gomp_task *stmt = as_a <gomp_task *> (gsi_stmt (*gsi));
  2065. /* Ignore task directives with empty bodies. */
  2066. if (optimize > 0
  2067. && empty_body_p (gimple_omp_body (stmt)))
  2068. {
  2069. gsi_replace (gsi, gimple_build_nop (), false);
  2070. return;
  2071. }
  2072. ctx = new_omp_context (stmt, outer_ctx);
  2073. taskreg_contexts.safe_push (ctx);
  2074. if (taskreg_nesting_level > 1)
  2075. ctx->is_nested = true;
  2076. ctx->field_map = splay_tree_new (splay_tree_compare_pointers, 0, 0);
  2077. ctx->default_kind = OMP_CLAUSE_DEFAULT_SHARED;
  2078. ctx->record_type = lang_hooks.types.make_type (RECORD_TYPE);
  2079. name = create_tmp_var_name (".omp_data_s");
  2080. name = build_decl (gimple_location (stmt),
  2081. TYPE_DECL, name, ctx->record_type);
  2082. DECL_ARTIFICIAL (name) = 1;
  2083. DECL_NAMELESS (name) = 1;
  2084. TYPE_NAME (ctx->record_type) = name;
  2085. TYPE_ARTIFICIAL (ctx->record_type) = 1;
  2086. create_omp_child_function (ctx, false);
  2087. gimple_omp_task_set_child_fn (stmt, ctx->cb.dst_fn);
  2088. scan_sharing_clauses (gimple_omp_task_clauses (stmt), ctx);
  2089. if (ctx->srecord_type)
  2090. {
  2091. name = create_tmp_var_name (".omp_data_a");
  2092. name = build_decl (gimple_location (stmt),
  2093. TYPE_DECL, name, ctx->srecord_type);
  2094. DECL_ARTIFICIAL (name) = 1;
  2095. DECL_NAMELESS (name) = 1;
  2096. TYPE_NAME (ctx->srecord_type) = name;
  2097. TYPE_ARTIFICIAL (ctx->srecord_type) = 1;
  2098. create_omp_child_function (ctx, true);
  2099. }
  2100. scan_omp (gimple_omp_body_ptr (stmt), ctx);
  2101. if (TYPE_FIELDS (ctx->record_type) == NULL)
  2102. {
  2103. ctx->record_type = ctx->receiver_decl = NULL;
  2104. t = build_int_cst (long_integer_type_node, 0);
  2105. gimple_omp_task_set_arg_size (stmt, t);
  2106. t = build_int_cst (long_integer_type_node, 1);
  2107. gimple_omp_task_set_arg_align (stmt, t);
  2108. }
  2109. }
  2110. /* If any decls have been made addressable during scan_omp,
  2111. adjust their fields if needed, and layout record types
  2112. of parallel/task constructs. */
  2113. static void
  2114. finish_taskreg_scan (omp_context *ctx)
  2115. {
  2116. if (ctx->record_type == NULL_TREE)
  2117. return;
  2118. /* If any task_shared_vars were needed, verify all
  2119. OMP_CLAUSE_SHARED clauses on GIMPLE_OMP_{PARALLEL,TASK}
  2120. statements if use_pointer_for_field hasn't changed
  2121. because of that. If it did, update field types now. */
  2122. if (task_shared_vars)
  2123. {
  2124. tree c;
  2125. for (c = gimple_omp_taskreg_clauses (ctx->stmt);
  2126. c; c = OMP_CLAUSE_CHAIN (c))
  2127. if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED)
  2128. {
  2129. tree decl = OMP_CLAUSE_DECL (c);
  2130. /* Global variables don't need to be copied,
  2131. the receiver side will use them directly. */
  2132. if (is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx)))
  2133. continue;
  2134. if (!bitmap_bit_p (task_shared_vars, DECL_UID (decl))
  2135. || !use_pointer_for_field (decl, ctx))
  2136. continue;
  2137. tree field = lookup_field (decl, ctx);
  2138. if (TREE_CODE (TREE_TYPE (field)) == POINTER_TYPE
  2139. && TREE_TYPE (TREE_TYPE (field)) == TREE_TYPE (decl))
  2140. continue;
  2141. TREE_TYPE (field) = build_pointer_type (TREE_TYPE (decl));
  2142. TREE_THIS_VOLATILE (field) = 0;
  2143. DECL_USER_ALIGN (field) = 0;
  2144. DECL_ALIGN (field) = TYPE_ALIGN (TREE_TYPE (field));
  2145. if (TYPE_ALIGN (ctx->record_type) < DECL_ALIGN (field))
  2146. TYPE_ALIGN (ctx->record_type) = DECL_ALIGN (field);
  2147. if (ctx->srecord_type)
  2148. {
  2149. tree sfield = lookup_sfield (decl, ctx);
  2150. TREE_TYPE (sfield) = TREE_TYPE (field);
  2151. TREE_THIS_VOLATILE (sfield) = 0;
  2152. DECL_USER_ALIGN (sfield) = 0;
  2153. DECL_ALIGN (sfield) = DECL_ALIGN (field);
  2154. if (TYPE_ALIGN (ctx->srecord_type) < DECL_ALIGN (sfield))
  2155. TYPE_ALIGN (ctx->srecord_type) = DECL_ALIGN (sfield);
  2156. }
  2157. }
  2158. }
  2159. if (gimple_code (ctx->stmt) == GIMPLE_OMP_PARALLEL)
  2160. {
  2161. layout_type (ctx->record_type);
  2162. fixup_child_record_type (ctx);
  2163. }
  2164. else
  2165. {
  2166. location_t loc = gimple_location (ctx->stmt);
  2167. tree *p, vla_fields = NULL_TREE, *q = &vla_fields;
  2168. /* Move VLA fields to the end. */
  2169. p = &TYPE_FIELDS (ctx->record_type);
  2170. while (*p)
  2171. if (!TYPE_SIZE_UNIT (TREE_TYPE (*p))
  2172. || ! TREE_CONSTANT (TYPE_SIZE_UNIT (TREE_TYPE (*p))))
  2173. {
  2174. *q = *p;
  2175. *p = TREE_CHAIN (*p);
  2176. TREE_CHAIN (*q) = NULL_TREE;
  2177. q = &TREE_CHAIN (*q);
  2178. }
  2179. else
  2180. p = &DECL_CHAIN (*p);
  2181. *p = vla_fields;
  2182. layout_type (ctx->record_type);
  2183. fixup_child_record_type (ctx);
  2184. if (ctx->srecord_type)
  2185. layout_type (ctx->srecord_type);
  2186. tree t = fold_convert_loc (loc, long_integer_type_node,
  2187. TYPE_SIZE_UNIT (ctx->record_type));
  2188. gimple_omp_task_set_arg_size (ctx->stmt, t);
  2189. t = build_int_cst (long_integer_type_node,
  2190. TYPE_ALIGN_UNIT (ctx->record_type));
  2191. gimple_omp_task_set_arg_align (ctx->stmt, t);
  2192. }
  2193. }
  2194. static omp_context *
  2195. enclosing_target_ctx (omp_context *ctx)
  2196. {
  2197. while (ctx != NULL
  2198. && gimple_code (ctx->stmt) != GIMPLE_OMP_TARGET)
  2199. ctx = ctx->outer;
  2200. gcc_assert (ctx != NULL);
  2201. return ctx;
  2202. }
  2203. static bool
  2204. oacc_loop_or_target_p (gimple stmt)
  2205. {
  2206. enum gimple_code outer_type = gimple_code (stmt);
  2207. return ((outer_type == GIMPLE_OMP_TARGET
  2208. && ((gimple_omp_target_kind (stmt)
  2209. == GF_OMP_TARGET_KIND_OACC_PARALLEL)
  2210. || (gimple_omp_target_kind (stmt)
  2211. == GF_OMP_TARGET_KIND_OACC_KERNELS)))
  2212. || (outer_type == GIMPLE_OMP_FOR
  2213. && gimple_omp_for_kind (stmt) == GF_OMP_FOR_KIND_OACC_LOOP));
  2214. }
  2215. /* Scan a GIMPLE_OMP_FOR. */
  2216. static void
  2217. scan_omp_for (gomp_for *stmt, omp_context *outer_ctx)
  2218. {
  2219. enum gimple_code outer_type = GIMPLE_ERROR_MARK;
  2220. omp_context *ctx;
  2221. size_t i;
  2222. tree clauses = gimple_omp_for_clauses (stmt);
  2223. if (outer_ctx)
  2224. outer_type = gimple_code (outer_ctx->stmt);
  2225. ctx = new_omp_context (stmt, outer_ctx);
  2226. if (is_gimple_omp_oacc (stmt))
  2227. {
  2228. if (outer_ctx && outer_type == GIMPLE_OMP_FOR)
  2229. ctx->gwv_this = outer_ctx->gwv_this;
  2230. for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
  2231. {
  2232. int val;
  2233. if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_GANG)
  2234. val = MASK_GANG;
  2235. else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_WORKER)
  2236. val = MASK_WORKER;
  2237. else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_VECTOR)
  2238. val = MASK_VECTOR;
  2239. else
  2240. continue;
  2241. ctx->gwv_this |= val;
  2242. if (!outer_ctx)
  2243. {
  2244. /* Skip; not nested inside a region. */
  2245. continue;
  2246. }
  2247. if (!oacc_loop_or_target_p (outer_ctx->stmt))
  2248. {
  2249. /* Skip; not nested inside an OpenACC region. */
  2250. continue;
  2251. }
  2252. if (outer_type == GIMPLE_OMP_FOR)
  2253. outer_ctx->gwv_below |= val;
  2254. if (OMP_CLAUSE_OPERAND (c, 0) != NULL_TREE)
  2255. {
  2256. omp_context *enclosing = enclosing_target_ctx (outer_ctx);
  2257. if (gimple_omp_target_kind (enclosing->stmt)
  2258. == GF_OMP_TARGET_KIND_OACC_PARALLEL)
  2259. error_at (gimple_location (stmt),
  2260. "no arguments allowed to gang, worker and vector clauses inside parallel");
  2261. }
  2262. }
  2263. }
  2264. scan_sharing_clauses (clauses, ctx);
  2265. scan_omp (gimple_omp_for_pre_body_ptr (stmt), ctx);
  2266. for (i = 0; i < gimple_omp_for_collapse (stmt); i++)
  2267. {
  2268. scan_omp_op (gimple_omp_for_index_ptr (stmt, i), ctx);
  2269. scan_omp_op (gimple_omp_for_initial_ptr (stmt, i), ctx);
  2270. scan_omp_op (gimple_omp_for_final_ptr (stmt, i), ctx);
  2271. scan_omp_op (gimple_omp_for_incr_ptr (stmt, i), ctx);
  2272. }
  2273. scan_omp (gimple_omp_body_ptr (stmt), ctx);
  2274. if (is_gimple_omp_oacc (stmt))
  2275. {
  2276. if (ctx->gwv_this & ctx->gwv_below)
  2277. error_at (gimple_location (stmt),
  2278. "gang, worker and vector may occur only once in a loop nest");
  2279. else if (ctx->gwv_below != 0
  2280. && ctx->gwv_this > ctx->gwv_below)
  2281. error_at (gimple_location (stmt),
  2282. "gang, worker and vector must occur in this order in a loop nest");
  2283. if (outer_ctx && outer_type == GIMPLE_OMP_FOR)
  2284. outer_ctx->gwv_below |= ctx->gwv_below;
  2285. }
  2286. }
  2287. /* Scan an OpenMP sections directive. */
  2288. static void
  2289. scan_omp_sections (gomp_sections *stmt, omp_context *outer_ctx)
  2290. {
  2291. omp_context *ctx;
  2292. ctx = new_omp_context (stmt, outer_ctx);
  2293. scan_sharing_clauses (gimple_omp_sections_clauses (stmt), ctx);
  2294. scan_omp (gimple_omp_body_ptr (stmt), ctx);
  2295. }
  2296. /* Scan an OpenMP single directive. */
  2297. static void
  2298. scan_omp_single (gomp_single *stmt, omp_context *outer_ctx)
  2299. {
  2300. omp_context *ctx;
  2301. tree name;
  2302. ctx = new_omp_context (stmt, outer_ctx);
  2303. ctx->field_map = splay_tree_new (splay_tree_compare_pointers, 0, 0);
  2304. ctx->record_type = lang_hooks.types.make_type (RECORD_TYPE);
  2305. name = create_tmp_var_name (".omp_copy_s");
  2306. name = build_decl (gimple_location (stmt),
  2307. TYPE_DECL, name, ctx->record_type);
  2308. TYPE_NAME (ctx->record_type) = name;
  2309. scan_sharing_clauses (gimple_omp_single_clauses (stmt), ctx);
  2310. scan_omp (gimple_omp_body_ptr (stmt), ctx);
  2311. if (TYPE_FIELDS (ctx->record_type) == NULL)
  2312. ctx->record_type = NULL;
  2313. else
  2314. layout_type (ctx->record_type);
  2315. }
  2316. /* Scan a GIMPLE_OMP_TARGET. */
  2317. static void
  2318. scan_omp_target (gomp_target *stmt, omp_context *outer_ctx)
  2319. {
  2320. omp_context *ctx;
  2321. tree name;
  2322. bool offloaded = is_gimple_omp_offloaded (stmt);
  2323. tree clauses = gimple_omp_target_clauses (stmt);
  2324. ctx = new_omp_context (stmt, outer_ctx);
  2325. ctx->field_map = splay_tree_new (splay_tree_compare_pointers, 0, 0);
  2326. ctx->default_kind = OMP_CLAUSE_DEFAULT_SHARED;
  2327. ctx->record_type = lang_hooks.types.make_type (RECORD_TYPE);
  2328. name = create_tmp_var_name (".omp_data_t");
  2329. name = build_decl (gimple_location (stmt),
  2330. TYPE_DECL, name, ctx->record_type);
  2331. DECL_ARTIFICIAL (name) = 1;
  2332. DECL_NAMELESS (name) = 1;
  2333. TYPE_NAME (ctx->record_type) = name;
  2334. TYPE_ARTIFICIAL (ctx->record_type) = 1;
  2335. if (offloaded)
  2336. {
  2337. if (is_gimple_omp_oacc (stmt))
  2338. ctx->reduction_map = splay_tree_new (splay_tree_compare_pointers,
  2339. 0, 0);
  2340. create_omp_child_function (ctx, false);
  2341. gimple_omp_target_set_child_fn (stmt, ctx->cb.dst_fn);
  2342. }
  2343. if (is_gimple_omp_oacc (stmt))
  2344. {
  2345. for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
  2346. {
  2347. if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_GANGS)
  2348. ctx->gwv_this |= MASK_GANG;
  2349. else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_WORKERS)
  2350. ctx->gwv_this |= MASK_WORKER;
  2351. else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_VECTOR_LENGTH)
  2352. ctx->gwv_this |= MASK_VECTOR;
  2353. }
  2354. }
  2355. scan_sharing_clauses (clauses, ctx);
  2356. scan_omp (gimple_omp_body_ptr (stmt), ctx);
  2357. if (TYPE_FIELDS (ctx->record_type) == NULL)
  2358. ctx->record_type = ctx->receiver_decl = NULL;
  2359. else
  2360. {
  2361. TYPE_FIELDS (ctx->record_type)
  2362. = nreverse (TYPE_FIELDS (ctx->record_type));
  2363. #ifdef ENABLE_CHECKING
  2364. tree field;
  2365. unsigned int align = DECL_ALIGN (TYPE_FIELDS (ctx->record_type));
  2366. for (field = TYPE_FIELDS (ctx->record_type);
  2367. field;
  2368. field = DECL_CHAIN (field))
  2369. gcc_assert (DECL_ALIGN (field) == align);
  2370. #endif
  2371. layout_type (ctx->record_type);
  2372. if (offloaded)
  2373. fixup_child_record_type (ctx);
  2374. }
  2375. }
  2376. /* Scan an OpenMP teams directive. */
  2377. static void
  2378. scan_omp_teams (gomp_teams *stmt, omp_context *outer_ctx)
  2379. {
  2380. omp_context *ctx = new_omp_context (stmt, outer_ctx);
  2381. scan_sharing_clauses (gimple_omp_teams_clauses (stmt), ctx);
  2382. scan_omp (gimple_omp_body_ptr (stmt), ctx);
  2383. }
  2384. /* Check nesting restrictions. */
  2385. static bool
  2386. check_omp_nesting_restrictions (gimple stmt, omp_context *ctx)
  2387. {
  2388. /* No nesting of non-OpenACC STMT (that is, an OpenMP one, or a GOMP builtin)
  2389. inside an OpenACC CTX. */
  2390. if (!(is_gimple_omp (stmt)
  2391. && is_gimple_omp_oacc (stmt)))
  2392. {
  2393. for (omp_context *ctx_ = ctx; ctx_ != NULL; ctx_ = ctx_->outer)
  2394. if (is_gimple_omp (ctx_->stmt)
  2395. && is_gimple_omp_oacc (ctx_->stmt))
  2396. {
  2397. error_at (gimple_location (stmt),
  2398. "non-OpenACC construct inside of OpenACC region");
  2399. return false;
  2400. }
  2401. }
  2402. if (ctx != NULL)
  2403. {
  2404. if (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
  2405. && gimple_omp_for_kind (ctx->stmt) & GF_OMP_FOR_SIMD)
  2406. {
  2407. error_at (gimple_location (stmt),
  2408. "OpenMP constructs may not be nested inside simd region");
  2409. return false;
  2410. }
  2411. else if (gimple_code (ctx->stmt) == GIMPLE_OMP_TEAMS)
  2412. {
  2413. if ((gimple_code (stmt) != GIMPLE_OMP_FOR
  2414. || (gimple_omp_for_kind (stmt)
  2415. != GF_OMP_FOR_KIND_DISTRIBUTE))
  2416. && gimple_code (stmt) != GIMPLE_OMP_PARALLEL)
  2417. {
  2418. error_at (gimple_location (stmt),
  2419. "only distribute or parallel constructs are allowed to "
  2420. "be closely nested inside teams construct");
  2421. return false;
  2422. }
  2423. }
  2424. }
  2425. switch (gimple_code (stmt))
  2426. {
  2427. case GIMPLE_OMP_FOR:
  2428. if (gimple_omp_for_kind (stmt) & GF_OMP_FOR_SIMD)
  2429. return true;
  2430. if (gimple_omp_for_kind (stmt) == GF_OMP_FOR_KIND_DISTRIBUTE)
  2431. {
  2432. if (ctx != NULL && gimple_code (ctx->stmt) != GIMPLE_OMP_TEAMS)
  2433. {
  2434. error_at (gimple_location (stmt),
  2435. "distribute construct must be closely nested inside "
  2436. "teams construct");
  2437. return false;
  2438. }
  2439. return true;
  2440. }
  2441. /* FALLTHRU */
  2442. case GIMPLE_CALL:
  2443. if (is_gimple_call (stmt)
  2444. && (DECL_FUNCTION_CODE (gimple_call_fndecl (stmt))
  2445. == BUILT_IN_GOMP_CANCEL
  2446. || DECL_FUNCTION_CODE (gimple_call_fndecl (stmt))
  2447. == BUILT_IN_GOMP_CANCELLATION_POINT))
  2448. {
  2449. const char *bad = NULL;
  2450. const char *kind = NULL;
  2451. if (ctx == NULL)
  2452. {
  2453. error_at (gimple_location (stmt), "orphaned %qs construct",
  2454. DECL_FUNCTION_CODE (gimple_call_fndecl (stmt))
  2455. == BUILT_IN_GOMP_CANCEL
  2456. ? "#pragma omp cancel"
  2457. : "#pragma omp cancellation point");
  2458. return false;
  2459. }
  2460. switch (tree_fits_shwi_p (gimple_call_arg (stmt, 0))
  2461. ? tree_to_shwi (gimple_call_arg (stmt, 0))
  2462. : 0)
  2463. {
  2464. case 1:
  2465. if (gimple_code (ctx->stmt) != GIMPLE_OMP_PARALLEL)
  2466. bad = "#pragma omp parallel";
  2467. else if (DECL_FUNCTION_CODE (gimple_call_fndecl (stmt))
  2468. == BUILT_IN_GOMP_CANCEL
  2469. && !integer_zerop (gimple_call_arg (stmt, 1)))
  2470. ctx->cancellable = true;
  2471. kind = "parallel";
  2472. break;
  2473. case 2:
  2474. if (gimple_code (ctx->stmt) != GIMPLE_OMP_FOR
  2475. || gimple_omp_for_kind (ctx->stmt) != GF_OMP_FOR_KIND_FOR)
  2476. bad = "#pragma omp for";
  2477. else if (DECL_FUNCTION_CODE (gimple_call_fndecl (stmt))
  2478. == BUILT_IN_GOMP_CANCEL
  2479. && !integer_zerop (gimple_call_arg (stmt, 1)))
  2480. {
  2481. ctx->cancellable = true;
  2482. if (find_omp_clause (gimple_omp_for_clauses (ctx->stmt),
  2483. OMP_CLAUSE_NOWAIT))
  2484. warning_at (gimple_location (stmt), 0,
  2485. "%<#pragma omp cancel for%> inside "
  2486. "%<nowait%> for construct");
  2487. if (find_omp_clause (gimple_omp_for_clauses (ctx->stmt),
  2488. OMP_CLAUSE_ORDERED))
  2489. warning_at (gimple_location (stmt), 0,
  2490. "%<#pragma omp cancel for%> inside "
  2491. "%<ordered%> for construct");
  2492. }
  2493. kind = "for";
  2494. break;
  2495. case 4:
  2496. if (gimple_code (ctx->stmt) != GIMPLE_OMP_SECTIONS
  2497. && gimple_code (ctx->stmt) != GIMPLE_OMP_SECTION)
  2498. bad = "#pragma omp sections";
  2499. else if (DECL_FUNCTION_CODE (gimple_call_fndecl (stmt))
  2500. == BUILT_IN_GOMP_CANCEL
  2501. && !integer_zerop (gimple_call_arg (stmt, 1)))
  2502. {
  2503. if (gimple_code (ctx->stmt) == GIMPLE_OMP_SECTIONS)
  2504. {
  2505. ctx->cancellable = true;
  2506. if (find_omp_clause (gimple_omp_sections_clauses
  2507. (ctx->stmt),
  2508. OMP_CLAUSE_NOWAIT))
  2509. warning_at (gimple_location (stmt), 0,
  2510. "%<#pragma omp cancel sections%> inside "
  2511. "%<nowait%> sections construct");
  2512. }
  2513. else
  2514. {
  2515. gcc_assert (ctx->outer
  2516. && gimple_code (ctx->outer->stmt)
  2517. == GIMPLE_OMP_SECTIONS);
  2518. ctx->outer->cancellable = true;
  2519. if (find_omp_clause (gimple_omp_sections_clauses
  2520. (ctx->outer->stmt),
  2521. OMP_CLAUSE_NOWAIT))
  2522. warning_at (gimple_location (stmt), 0,
  2523. "%<#pragma omp cancel sections%> inside "
  2524. "%<nowait%> sections construct");
  2525. }
  2526. }
  2527. kind = "sections";
  2528. break;
  2529. case 8:
  2530. if (gimple_code (ctx->stmt) != GIMPLE_OMP_TASK)
  2531. bad = "#pragma omp task";
  2532. else
  2533. ctx->cancellable = true;
  2534. kind = "taskgroup";
  2535. break;
  2536. default:
  2537. error_at (gimple_location (stmt), "invalid arguments");
  2538. return false;
  2539. }
  2540. if (bad)
  2541. {
  2542. error_at (gimple_location (stmt),
  2543. "%<%s %s%> construct not closely nested inside of %qs",
  2544. DECL_FUNCTION_CODE (gimple_call_fndecl (stmt))
  2545. == BUILT_IN_GOMP_CANCEL
  2546. ? "#pragma omp cancel"
  2547. : "#pragma omp cancellation point", kind, bad);
  2548. return false;
  2549. }
  2550. }
  2551. /* FALLTHRU */
  2552. case GIMPLE_OMP_SECTIONS:
  2553. case GIMPLE_OMP_SINGLE:
  2554. for (; ctx != NULL; ctx = ctx->outer)
  2555. switch (gimple_code (ctx->stmt))
  2556. {
  2557. case GIMPLE_OMP_FOR:
  2558. case GIMPLE_OMP_SECTIONS:
  2559. case GIMPLE_OMP_SINGLE:
  2560. case GIMPLE_OMP_ORDERED:
  2561. case GIMPLE_OMP_MASTER:
  2562. case GIMPLE_OMP_TASK:
  2563. case GIMPLE_OMP_CRITICAL:
  2564. if (is_gimple_call (stmt))
  2565. {
  2566. if (DECL_FUNCTION_CODE (gimple_call_fndecl (stmt))
  2567. != BUILT_IN_GOMP_BARRIER)
  2568. return true;
  2569. error_at (gimple_location (stmt),
  2570. "barrier region may not be closely nested inside "
  2571. "of work-sharing, critical, ordered, master or "
  2572. "explicit task region");
  2573. return false;
  2574. }
  2575. error_at (gimple_location (stmt),
  2576. "work-sharing region may not be closely nested inside "
  2577. "of work-sharing, critical, ordered, master or explicit "
  2578. "task region");
  2579. return false;
  2580. case GIMPLE_OMP_PARALLEL:
  2581. return true;
  2582. default:
  2583. break;
  2584. }
  2585. break;
  2586. case GIMPLE_OMP_MASTER:
  2587. for (; ctx != NULL; ctx = ctx->outer)
  2588. switch (gimple_code (ctx->stmt))
  2589. {
  2590. case GIMPLE_OMP_FOR:
  2591. case GIMPLE_OMP_SECTIONS:
  2592. case GIMPLE_OMP_SINGLE:
  2593. case GIMPLE_OMP_TASK:
  2594. error_at (gimple_location (stmt),
  2595. "master region may not be closely nested inside "
  2596. "of work-sharing or explicit task region");
  2597. return false;
  2598. case GIMPLE_OMP_PARALLEL:
  2599. return true;
  2600. default:
  2601. break;
  2602. }
  2603. break;
  2604. case GIMPLE_OMP_ORDERED:
  2605. for (; ctx != NULL; ctx = ctx->outer)
  2606. switch (gimple_code (ctx->stmt))
  2607. {
  2608. case GIMPLE_OMP_CRITICAL:
  2609. case GIMPLE_OMP_TASK:
  2610. error_at (gimple_location (stmt),
  2611. "ordered region may not be closely nested inside "
  2612. "of critical or explicit task region");
  2613. return false;
  2614. case GIMPLE_OMP_FOR:
  2615. if (find_omp_clause (gimple_omp_for_clauses (ctx->stmt),
  2616. OMP_CLAUSE_ORDERED) == NULL)
  2617. {
  2618. error_at (gimple_location (stmt),
  2619. "ordered region must be closely nested inside "
  2620. "a loop region with an ordered clause");
  2621. return false;
  2622. }
  2623. return true;
  2624. case GIMPLE_OMP_PARALLEL:
  2625. error_at (gimple_location (stmt),
  2626. "ordered region must be closely nested inside "
  2627. "a loop region with an ordered clause");
  2628. return false;
  2629. default:
  2630. break;
  2631. }
  2632. break;
  2633. case GIMPLE_OMP_CRITICAL:
  2634. {
  2635. tree this_stmt_name
  2636. = gimple_omp_critical_name (as_a <gomp_critical *> (stmt));
  2637. for (; ctx != NULL; ctx = ctx->outer)
  2638. if (gomp_critical *other_crit
  2639. = dyn_cast <gomp_critical *> (ctx->stmt))
  2640. if (this_stmt_name == gimple_omp_critical_name (other_crit))
  2641. {
  2642. error_at (gimple_location (stmt),
  2643. "critical region may not be nested inside a critical "
  2644. "region with the same name");
  2645. return false;
  2646. }
  2647. }
  2648. break;
  2649. case GIMPLE_OMP_TEAMS:
  2650. if (ctx == NULL
  2651. || gimple_code (ctx->stmt) != GIMPLE_OMP_TARGET
  2652. || gimple_omp_target_kind (ctx->stmt) != GF_OMP_TARGET_KIND_REGION)
  2653. {
  2654. error_at (gimple_location (stmt),
  2655. "teams construct not closely nested inside of target "
  2656. "region");
  2657. return false;
  2658. }
  2659. break;
  2660. case GIMPLE_OMP_TARGET:
  2661. for (; ctx != NULL; ctx = ctx->outer)
  2662. {
  2663. if (gimple_code (ctx->stmt) != GIMPLE_OMP_TARGET)
  2664. {
  2665. if (is_gimple_omp (stmt)
  2666. && is_gimple_omp_oacc (stmt)
  2667. && is_gimple_omp (ctx->stmt))
  2668. {
  2669. error_at (gimple_location (stmt),
  2670. "OpenACC construct inside of non-OpenACC region");
  2671. return false;
  2672. }
  2673. continue;
  2674. }
  2675. const char *stmt_name, *ctx_stmt_name;
  2676. switch (gimple_omp_target_kind (stmt))
  2677. {
  2678. case GF_OMP_TARGET_KIND_REGION: stmt_name = "target"; break;
  2679. case GF_OMP_TARGET_KIND_DATA: stmt_name = "target data"; break;
  2680. case GF_OMP_TARGET_KIND_UPDATE: stmt_name = "target update"; break;
  2681. case GF_OMP_TARGET_KIND_OACC_PARALLEL: stmt_name = "parallel"; break;
  2682. case GF_OMP_TARGET_KIND_OACC_KERNELS: stmt_name = "kernels"; break;
  2683. case GF_OMP_TARGET_KIND_OACC_DATA: stmt_name = "data"; break;
  2684. case GF_OMP_TARGET_KIND_OACC_UPDATE: stmt_name = "update"; break;
  2685. case GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA: stmt_name = "enter/exit data"; break;
  2686. default: gcc_unreachable ();
  2687. }
  2688. switch (gimple_omp_target_kind (ctx->stmt))
  2689. {
  2690. case GF_OMP_TARGET_KIND_REGION: ctx_stmt_name = "target"; break;
  2691. case GF_OMP_TARGET_KIND_DATA: ctx_stmt_name = "target data"; break;
  2692. case GF_OMP_TARGET_KIND_OACC_PARALLEL: ctx_stmt_name = "parallel"; break;
  2693. case GF_OMP_TARGET_KIND_OACC_KERNELS: ctx_stmt_name = "kernels"; break;
  2694. case GF_OMP_TARGET_KIND_OACC_DATA: ctx_stmt_name = "data"; break;
  2695. default: gcc_unreachable ();
  2696. }
  2697. /* OpenACC/OpenMP mismatch? */
  2698. if (is_gimple_omp_oacc (stmt)
  2699. != is_gimple_omp_oacc (ctx->stmt))
  2700. {
  2701. error_at (gimple_location (stmt),
  2702. "%s %s construct inside of %s %s region",
  2703. (is_gimple_omp_oacc (stmt)
  2704. ? "OpenACC" : "OpenMP"), stmt_name,
  2705. (is_gimple_omp_oacc (ctx->stmt)
  2706. ? "OpenACC" : "OpenMP"), ctx_stmt_name);
  2707. return false;
  2708. }
  2709. if (is_gimple_omp_offloaded (ctx->stmt))
  2710. {
  2711. /* No GIMPLE_OMP_TARGET inside offloaded OpenACC CTX. */
  2712. if (is_gimple_omp_oacc (ctx->stmt))
  2713. {
  2714. error_at (gimple_location (stmt),
  2715. "%s construct inside of %s region",
  2716. stmt_name, ctx_stmt_name);
  2717. return false;
  2718. }
  2719. else
  2720. {
  2721. gcc_checking_assert (!is_gimple_omp_oacc (stmt));
  2722. warning_at (gimple_location (stmt), 0,
  2723. "%s construct inside of %s region",
  2724. stmt_name, ctx_stmt_name);
  2725. }
  2726. }
  2727. }
  2728. break;
  2729. default:
  2730. break;
  2731. }
  2732. return true;
  2733. }
  2734. /* Helper function scan_omp.
  2735. Callback for walk_tree or operators in walk_gimple_stmt used to
  2736. scan for OMP directives in TP. */
  2737. static tree
  2738. scan_omp_1_op (tree *tp, int *walk_subtrees, void *data)
  2739. {
  2740. struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
  2741. omp_context *ctx = (omp_context *) wi->info;
  2742. tree t = *tp;
  2743. switch (TREE_CODE (t))
  2744. {
  2745. case VAR_DECL:
  2746. case PARM_DECL:
  2747. case LABEL_DECL:
  2748. case RESULT_DECL:
  2749. if (ctx)
  2750. *tp = remap_decl (t, &ctx->cb);
  2751. break;
  2752. default:
  2753. if (ctx && TYPE_P (t))
  2754. *tp = remap_type (t, &ctx->cb);
  2755. else if (!DECL_P (t))
  2756. {
  2757. *walk_subtrees = 1;
  2758. if (ctx)
  2759. {
  2760. tree tem = remap_type (TREE_TYPE (t), &ctx->cb);
  2761. if (tem != TREE_TYPE (t))
  2762. {
  2763. if (TREE_CODE (t) == INTEGER_CST)
  2764. *tp = wide_int_to_tree (tem, t);
  2765. else
  2766. TREE_TYPE (t) = tem;
  2767. }
  2768. }
  2769. }
  2770. break;
  2771. }
  2772. return NULL_TREE;
  2773. }
  2774. /* Return true if FNDECL is a setjmp or a longjmp. */
  2775. static bool
  2776. setjmp_or_longjmp_p (const_tree fndecl)
  2777. {
  2778. if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
  2779. && (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_SETJMP
  2780. || DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LONGJMP))
  2781. return true;
  2782. tree declname = DECL_NAME (fndecl);
  2783. if (!declname)
  2784. return false;
  2785. const char *name = IDENTIFIER_POINTER (declname);
  2786. return !strcmp (name, "setjmp") || !strcmp (name, "longjmp");
  2787. }
  2788. /* Helper function for scan_omp.
  2789. Callback for walk_gimple_stmt used to scan for OMP directives in
  2790. the current statement in GSI. */
  2791. static tree
  2792. scan_omp_1_stmt (gimple_stmt_iterator *gsi, bool *handled_ops_p,
  2793. struct walk_stmt_info *wi)
  2794. {
  2795. gimple stmt = gsi_stmt (*gsi);
  2796. omp_context *ctx = (omp_context *) wi->info;
  2797. if (gimple_has_location (stmt))
  2798. input_location = gimple_location (stmt);
  2799. /* Check the nesting restrictions. */
  2800. bool remove = false;
  2801. if (is_gimple_omp (stmt))
  2802. remove = !check_omp_nesting_restrictions (stmt, ctx);
  2803. else if (is_gimple_call (stmt))
  2804. {
  2805. tree fndecl = gimple_call_fndecl (stmt);
  2806. if (fndecl)
  2807. {
  2808. if (setjmp_or_longjmp_p (fndecl)
  2809. && ctx
  2810. && gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
  2811. && gimple_omp_for_kind (ctx->stmt) & GF_OMP_FOR_SIMD)
  2812. {
  2813. remove = true;
  2814. error_at (gimple_location (stmt),
  2815. "setjmp/longjmp inside simd construct");
  2816. }
  2817. else if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
  2818. switch (DECL_FUNCTION_CODE (fndecl))
  2819. {
  2820. case BUILT_IN_GOMP_BARRIER:
  2821. case BUILT_IN_GOMP_CANCEL:
  2822. case BUILT_IN_GOMP_CANCELLATION_POINT:
  2823. case BUILT_IN_GOMP_TASKYIELD:
  2824. case BUILT_IN_GOMP_TASKWAIT:
  2825. case BUILT_IN_GOMP_TASKGROUP_START:
  2826. case BUILT_IN_GOMP_TASKGROUP_END:
  2827. remove = !check_omp_nesting_restrictions (stmt, ctx);
  2828. break;
  2829. default:
  2830. break;
  2831. }
  2832. }
  2833. }
  2834. if (remove)
  2835. {
  2836. stmt = gimple_build_nop ();
  2837. gsi_replace (gsi, stmt, false);
  2838. }
  2839. *handled_ops_p = true;
  2840. switch (gimple_code (stmt))
  2841. {
  2842. case GIMPLE_OMP_PARALLEL:
  2843. taskreg_nesting_level++;
  2844. scan_omp_parallel (gsi, ctx);
  2845. taskreg_nesting_level--;
  2846. break;
  2847. case GIMPLE_OMP_TASK:
  2848. taskreg_nesting_level++;
  2849. scan_omp_task (gsi, ctx);
  2850. taskreg_nesting_level--;
  2851. break;
  2852. case GIMPLE_OMP_FOR:
  2853. scan_omp_for (as_a <gomp_for *> (stmt), ctx);
  2854. break;
  2855. case GIMPLE_OMP_SECTIONS:
  2856. scan_omp_sections (as_a <gomp_sections *> (stmt), ctx);
  2857. break;
  2858. case GIMPLE_OMP_SINGLE:
  2859. scan_omp_single (as_a <gomp_single *> (stmt), ctx);
  2860. break;
  2861. case GIMPLE_OMP_SECTION:
  2862. case GIMPLE_OMP_MASTER:
  2863. case GIMPLE_OMP_TASKGROUP:
  2864. case GIMPLE_OMP_ORDERED:
  2865. case GIMPLE_OMP_CRITICAL:
  2866. ctx = new_omp_context (stmt, ctx);
  2867. scan_omp (gimple_omp_body_ptr (stmt), ctx);
  2868. break;
  2869. case GIMPLE_OMP_TARGET:
  2870. scan_omp_target (as_a <gomp_target *> (stmt), ctx);
  2871. break;
  2872. case GIMPLE_OMP_TEAMS:
  2873. scan_omp_teams (as_a <gomp_teams *> (stmt), ctx);
  2874. break;
  2875. case GIMPLE_BIND:
  2876. {
  2877. tree var;
  2878. *handled_ops_p = false;
  2879. if (ctx)
  2880. for (var = gimple_bind_vars (as_a <gbind *> (stmt));
  2881. var ;
  2882. var = DECL_CHAIN (var))
  2883. insert_decl_map (&ctx->cb, var, var);
  2884. }
  2885. break;
  2886. default:
  2887. *handled_ops_p = false;
  2888. break;
  2889. }
  2890. return NULL_TREE;
  2891. }
  2892. /* Scan all the statements starting at the current statement. CTX
  2893. contains context information about the OMP directives and
  2894. clauses found during the scan. */
  2895. static void
  2896. scan_omp (gimple_seq *body_p, omp_context *ctx)
  2897. {
  2898. location_t saved_location;
  2899. struct walk_stmt_info wi;
  2900. memset (&wi, 0, sizeof (wi));
  2901. wi.info = ctx;
  2902. wi.want_locations = true;
  2903. saved_location = input_location;
  2904. walk_gimple_seq_mod (body_p, scan_omp_1_stmt, scan_omp_1_op, &wi);
  2905. input_location = saved_location;
  2906. }
  2907. /* Re-gimplification and code generation routines. */
  2908. /* Build a call to GOMP_barrier. */
  2909. static gimple
  2910. build_omp_barrier (tree lhs)
  2911. {
  2912. tree fndecl = builtin_decl_explicit (lhs ? BUILT_IN_GOMP_BARRIER_CANCEL
  2913. : BUILT_IN_GOMP_BARRIER);
  2914. gcall *g = gimple_build_call (fndecl, 0);
  2915. if (lhs)
  2916. gimple_call_set_lhs (g, lhs);
  2917. return g;
  2918. }
  2919. /* If a context was created for STMT when it was scanned, return it. */
  2920. static omp_context *
  2921. maybe_lookup_ctx (gimple stmt)
  2922. {
  2923. splay_tree_node n;
  2924. n = splay_tree_lookup (all_contexts, (splay_tree_key) stmt);
  2925. return n ? (omp_context *) n->value : NULL;
  2926. }
  2927. /* Find the mapping for DECL in CTX or the immediately enclosing
  2928. context that has a mapping for DECL.
  2929. If CTX is a nested parallel directive, we may have to use the decl
  2930. mappings created in CTX's parent context. Suppose that we have the
  2931. following parallel nesting (variable UIDs showed for clarity):
  2932. iD.1562 = 0;
  2933. #omp parallel shared(iD.1562) -> outer parallel
  2934. iD.1562 = iD.1562 + 1;
  2935. #omp parallel shared (iD.1562) -> inner parallel
  2936. iD.1562 = iD.1562 - 1;
  2937. Each parallel structure will create a distinct .omp_data_s structure
  2938. for copying iD.1562 in/out of the directive:
  2939. outer parallel .omp_data_s.1.i -> iD.1562
  2940. inner parallel .omp_data_s.2.i -> iD.1562
  2941. A shared variable mapping will produce a copy-out operation before
  2942. the parallel directive and a copy-in operation after it. So, in
  2943. this case we would have:
  2944. iD.1562 = 0;
  2945. .omp_data_o.1.i = iD.1562;
  2946. #omp parallel shared(iD.1562) -> outer parallel
  2947. .omp_data_i.1 = &.omp_data_o.1
  2948. .omp_data_i.1->i = .omp_data_i.1->i + 1;
  2949. .omp_data_o.2.i = iD.1562; -> **
  2950. #omp parallel shared(iD.1562) -> inner parallel
  2951. .omp_data_i.2 = &.omp_data_o.2
  2952. .omp_data_i.2->i = .omp_data_i.2->i - 1;
  2953. ** This is a problem. The symbol iD.1562 cannot be referenced
  2954. inside the body of the outer parallel region. But since we are
  2955. emitting this copy operation while expanding the inner parallel
  2956. directive, we need to access the CTX structure of the outer
  2957. parallel directive to get the correct mapping:
  2958. .omp_data_o.2.i = .omp_data_i.1->i
  2959. Since there may be other workshare or parallel directives enclosing
  2960. the parallel directive, it may be necessary to walk up the context
  2961. parent chain. This is not a problem in general because nested
  2962. parallelism happens only rarely. */
  2963. static tree
  2964. lookup_decl_in_outer_ctx (tree decl, omp_context *ctx)
  2965. {
  2966. tree t;
  2967. omp_context *up;
  2968. for (up = ctx->outer, t = NULL; up && t == NULL; up = up->outer)
  2969. t = maybe_lookup_decl (decl, up);
  2970. gcc_assert (!ctx->is_nested || t || is_global_var (decl));
  2971. return t ? t : decl;
  2972. }
  2973. /* Similar to lookup_decl_in_outer_ctx, but return DECL if not found
  2974. in outer contexts. */
  2975. static tree
  2976. maybe_lookup_decl_in_outer_ctx (tree decl, omp_context *ctx)
  2977. {
  2978. tree t = NULL;
  2979. omp_context *up;
  2980. for (up = ctx->outer, t = NULL; up && t == NULL; up = up->outer)
  2981. t = maybe_lookup_decl (decl, up);
  2982. return t ? t : decl;
  2983. }
  2984. /* Construct the initialization value for reduction CLAUSE. */
  2985. tree
  2986. omp_reduction_init (tree clause, tree type)
  2987. {
  2988. location_t loc = OMP_CLAUSE_LOCATION (clause);
  2989. switch (OMP_CLAUSE_REDUCTION_CODE (clause))
  2990. {
  2991. case PLUS_EXPR:
  2992. case MINUS_EXPR:
  2993. case BIT_IOR_EXPR:
  2994. case BIT_XOR_EXPR:
  2995. case TRUTH_OR_EXPR:
  2996. case TRUTH_ORIF_EXPR:
  2997. case TRUTH_XOR_EXPR:
  2998. case NE_EXPR:
  2999. return build_zero_cst (type);
  3000. case MULT_EXPR:
  3001. case TRUTH_AND_EXPR:
  3002. case TRUTH_ANDIF_EXPR:
  3003. case EQ_EXPR:
  3004. return fold_convert_loc (loc, type, integer_one_node);
  3005. case BIT_AND_EXPR:
  3006. return fold_convert_loc (loc, type, integer_minus_one_node);
  3007. case MAX_EXPR:
  3008. if (SCALAR_FLOAT_TYPE_P (type))
  3009. {
  3010. REAL_VALUE_TYPE max, min;
  3011. if (HONOR_INFINITIES (type))
  3012. {
  3013. real_inf (&max);
  3014. real_arithmetic (&min, NEGATE_EXPR, &max, NULL);
  3015. }
  3016. else
  3017. real_maxval (&min, 1, TYPE_MODE (type));
  3018. return build_real (type, min);
  3019. }
  3020. else
  3021. {
  3022. gcc_assert (INTEGRAL_TYPE_P (type));
  3023. return TYPE_MIN_VALUE (type);
  3024. }
  3025. case MIN_EXPR:
  3026. if (SCALAR_FLOAT_TYPE_P (type))
  3027. {
  3028. REAL_VALUE_TYPE max;
  3029. if (HONOR_INFINITIES (type))
  3030. real_inf (&max);
  3031. else
  3032. real_maxval (&max, 0, TYPE_MODE (type));
  3033. return build_real (type, max);
  3034. }
  3035. else
  3036. {
  3037. gcc_assert (INTEGRAL_TYPE_P (type));
  3038. return TYPE_MAX_VALUE (type);
  3039. }
  3040. default:
  3041. gcc_unreachable ();
  3042. }
  3043. }
  3044. /* Return alignment to be assumed for var in CLAUSE, which should be
  3045. OMP_CLAUSE_ALIGNED. */
  3046. static tree
  3047. omp_clause_aligned_alignment (tree clause)
  3048. {
  3049. if (OMP_CLAUSE_ALIGNED_ALIGNMENT (clause))
  3050. return OMP_CLAUSE_ALIGNED_ALIGNMENT (clause);
  3051. /* Otherwise return implementation defined alignment. */
  3052. unsigned int al = 1;
  3053. machine_mode mode, vmode;
  3054. int vs = targetm.vectorize.autovectorize_vector_sizes ();
  3055. if (vs)
  3056. vs = 1 << floor_log2 (vs);
  3057. static enum mode_class classes[]
  3058. = { MODE_INT, MODE_VECTOR_INT, MODE_FLOAT, MODE_VECTOR_FLOAT };
  3059. for (int i = 0; i < 4; i += 2)
  3060. for (mode = GET_CLASS_NARROWEST_MODE (classes[i]);
  3061. mode != VOIDmode;
  3062. mode = GET_MODE_WIDER_MODE (mode))
  3063. {
  3064. vmode = targetm.vectorize.preferred_simd_mode (mode);
  3065. if (GET_MODE_CLASS (vmode) != classes[i + 1])
  3066. continue;
  3067. while (vs
  3068. && GET_MODE_SIZE (vmode) < vs
  3069. && GET_MODE_2XWIDER_MODE (vmode) != VOIDmode)
  3070. vmode = GET_MODE_2XWIDER_MODE (vmode);
  3071. tree type = lang_hooks.types.type_for_mode (mode, 1);
  3072. if (type == NULL_TREE || TYPE_MODE (type) != mode)
  3073. continue;
  3074. type = build_vector_type (type, GET_MODE_SIZE (vmode)
  3075. / GET_MODE_SIZE (mode));
  3076. if (TYPE_MODE (type) != vmode)
  3077. continue;
  3078. if (TYPE_ALIGN_UNIT (type) > al)
  3079. al = TYPE_ALIGN_UNIT (type);
  3080. }
  3081. return build_int_cst (integer_type_node, al);
  3082. }
  3083. /* Return maximum possible vectorization factor for the target. */
  3084. static int
  3085. omp_max_vf (void)
  3086. {
  3087. if (!optimize
  3088. || optimize_debug
  3089. || !flag_tree_loop_optimize
  3090. || (!flag_tree_loop_vectorize
  3091. && (global_options_set.x_flag_tree_loop_vectorize
  3092. || global_options_set.x_flag_tree_vectorize)))
  3093. return 1;
  3094. int vs = targetm.vectorize.autovectorize_vector_sizes ();
  3095. if (vs)
  3096. {
  3097. vs = 1 << floor_log2 (vs);
  3098. return vs;
  3099. }
  3100. machine_mode vqimode = targetm.vectorize.preferred_simd_mode (QImode);
  3101. if (GET_MODE_CLASS (vqimode) == MODE_VECTOR_INT)
  3102. return GET_MODE_NUNITS (vqimode);
  3103. return 1;
  3104. }
  3105. /* Helper function of lower_rec_input_clauses, used for #pragma omp simd
  3106. privatization. */
  3107. static bool
  3108. lower_rec_simd_input_clauses (tree new_var, omp_context *ctx, int &max_vf,
  3109. tree &idx, tree &lane, tree &ivar, tree &lvar)
  3110. {
  3111. if (max_vf == 0)
  3112. {
  3113. max_vf = omp_max_vf ();
  3114. if (max_vf > 1)
  3115. {
  3116. tree c = find_omp_clause (gimple_omp_for_clauses (ctx->stmt),
  3117. OMP_CLAUSE_SAFELEN);
  3118. if (c && TREE_CODE (OMP_CLAUSE_SAFELEN_EXPR (c)) != INTEGER_CST)
  3119. max_vf = 1;
  3120. else if (c && compare_tree_int (OMP_CLAUSE_SAFELEN_EXPR (c),
  3121. max_vf) == -1)
  3122. max_vf = tree_to_shwi (OMP_CLAUSE_SAFELEN_EXPR (c));
  3123. }
  3124. if (max_vf > 1)
  3125. {
  3126. idx = create_tmp_var (unsigned_type_node);
  3127. lane = create_tmp_var (unsigned_type_node);
  3128. }
  3129. }
  3130. if (max_vf == 1)
  3131. return false;
  3132. tree atype = build_array_type_nelts (TREE_TYPE (new_var), max_vf);
  3133. tree avar = create_tmp_var_raw (atype);
  3134. if (TREE_ADDRESSABLE (new_var))
  3135. TREE_ADDRESSABLE (avar) = 1;
  3136. DECL_ATTRIBUTES (avar)
  3137. = tree_cons (get_identifier ("omp simd array"), NULL,
  3138. DECL_ATTRIBUTES (avar));
  3139. gimple_add_tmp_var (avar);
  3140. ivar = build4 (ARRAY_REF, TREE_TYPE (new_var), avar, idx,
  3141. NULL_TREE, NULL_TREE);
  3142. lvar = build4 (ARRAY_REF, TREE_TYPE (new_var), avar, lane,
  3143. NULL_TREE, NULL_TREE);
  3144. if (DECL_P (new_var))
  3145. {
  3146. SET_DECL_VALUE_EXPR (new_var, lvar);
  3147. DECL_HAS_VALUE_EXPR_P (new_var) = 1;
  3148. }
  3149. return true;
  3150. }
  3151. /* Helper function of lower_rec_input_clauses. For a reference
  3152. in simd reduction, add an underlying variable it will reference. */
  3153. static void
  3154. handle_simd_reference (location_t loc, tree new_vard, gimple_seq *ilist)
  3155. {
  3156. tree z = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (new_vard)));
  3157. if (TREE_CONSTANT (z))
  3158. {
  3159. const char *name = NULL;
  3160. if (DECL_NAME (new_vard))
  3161. name = IDENTIFIER_POINTER (DECL_NAME (new_vard));
  3162. z = create_tmp_var_raw (TREE_TYPE (TREE_TYPE (new_vard)), name);
  3163. gimple_add_tmp_var (z);
  3164. TREE_ADDRESSABLE (z) = 1;
  3165. z = build_fold_addr_expr_loc (loc, z);
  3166. gimplify_assign (new_vard, z, ilist);
  3167. }
  3168. }
  3169. /* Generate code to implement the input clauses, FIRSTPRIVATE and COPYIN,
  3170. from the receiver (aka child) side and initializers for REFERENCE_TYPE
  3171. private variables. Initialization statements go in ILIST, while calls
  3172. to destructors go in DLIST. */
  3173. static void
  3174. lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
  3175. omp_context *ctx, struct omp_for_data *fd)
  3176. {
  3177. tree c, dtor, copyin_seq, x, ptr;
  3178. bool copyin_by_ref = false;
  3179. bool lastprivate_firstprivate = false;
  3180. bool reduction_omp_orig_ref = false;
  3181. int pass;
  3182. bool is_simd = (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
  3183. && gimple_omp_for_kind (ctx->stmt) & GF_OMP_FOR_SIMD);
  3184. int max_vf = 0;
  3185. tree lane = NULL_TREE, idx = NULL_TREE;
  3186. tree ivar = NULL_TREE, lvar = NULL_TREE;
  3187. gimple_seq llist[2] = { NULL, NULL };
  3188. copyin_seq = NULL;
  3189. /* Set max_vf=1 (which will later enforce safelen=1) in simd loops
  3190. with data sharing clauses referencing variable sized vars. That
  3191. is unnecessarily hard to support and very unlikely to result in
  3192. vectorized code anyway. */
  3193. if (is_simd)
  3194. for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
  3195. switch (OMP_CLAUSE_CODE (c))
  3196. {
  3197. case OMP_CLAUSE_LINEAR:
  3198. if (OMP_CLAUSE_LINEAR_ARRAY (c))
  3199. max_vf = 1;
  3200. /* FALLTHRU */
  3201. case OMP_CLAUSE_REDUCTION:
  3202. case OMP_CLAUSE_PRIVATE:
  3203. case OMP_CLAUSE_FIRSTPRIVATE:
  3204. case OMP_CLAUSE_LASTPRIVATE:
  3205. if (is_variable_sized (OMP_CLAUSE_DECL (c)))
  3206. max_vf = 1;
  3207. break;
  3208. default:
  3209. continue;
  3210. }
  3211. /* Do all the fixed sized types in the first pass, and the variable sized
  3212. types in the second pass. This makes sure that the scalar arguments to
  3213. the variable sized types are processed before we use them in the
  3214. variable sized operations. */
  3215. for (pass = 0; pass < 2; ++pass)
  3216. {
  3217. for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
  3218. {
  3219. enum omp_clause_code c_kind = OMP_CLAUSE_CODE (c);
  3220. tree var, new_var;
  3221. bool by_ref;
  3222. location_t clause_loc = OMP_CLAUSE_LOCATION (c);
  3223. switch (c_kind)
  3224. {
  3225. case OMP_CLAUSE_PRIVATE:
  3226. if (OMP_CLAUSE_PRIVATE_DEBUG (c))
  3227. continue;
  3228. break;
  3229. case OMP_CLAUSE_SHARED:
  3230. /* Ignore shared directives in teams construct. */
  3231. if (gimple_code (ctx->stmt) == GIMPLE_OMP_TEAMS)
  3232. continue;
  3233. if (maybe_lookup_decl (OMP_CLAUSE_DECL (c), ctx) == NULL)
  3234. {
  3235. gcc_assert (is_global_var (OMP_CLAUSE_DECL (c)));
  3236. continue;
  3237. }
  3238. case OMP_CLAUSE_FIRSTPRIVATE:
  3239. case OMP_CLAUSE_COPYIN:
  3240. case OMP_CLAUSE_LINEAR:
  3241. break;
  3242. case OMP_CLAUSE_REDUCTION:
  3243. if (OMP_CLAUSE_REDUCTION_OMP_ORIG_REF (c))
  3244. reduction_omp_orig_ref = true;
  3245. break;
  3246. case OMP_CLAUSE__LOOPTEMP_:
  3247. /* Handle _looptemp_ clauses only on parallel. */
  3248. if (fd)
  3249. continue;
  3250. break;
  3251. case OMP_CLAUSE_LASTPRIVATE:
  3252. if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
  3253. {
  3254. lastprivate_firstprivate = true;
  3255. if (pass != 0)
  3256. continue;
  3257. }
  3258. /* Even without corresponding firstprivate, if
  3259. decl is Fortran allocatable, it needs outer var
  3260. reference. */
  3261. else if (pass == 0
  3262. && lang_hooks.decls.omp_private_outer_ref
  3263. (OMP_CLAUSE_DECL (c)))
  3264. lastprivate_firstprivate = true;
  3265. break;
  3266. case OMP_CLAUSE_ALIGNED:
  3267. if (pass == 0)
  3268. continue;
  3269. var = OMP_CLAUSE_DECL (c);
  3270. if (TREE_CODE (TREE_TYPE (var)) == POINTER_TYPE
  3271. && !is_global_var (var))
  3272. {
  3273. new_var = maybe_lookup_decl (var, ctx);
  3274. if (new_var == NULL_TREE)
  3275. new_var = maybe_lookup_decl_in_outer_ctx (var, ctx);
  3276. x = builtin_decl_explicit (BUILT_IN_ASSUME_ALIGNED);
  3277. x = build_call_expr_loc (clause_loc, x, 2, new_var,
  3278. omp_clause_aligned_alignment (c));
  3279. x = fold_convert_loc (clause_loc, TREE_TYPE (new_var), x);
  3280. x = build2 (MODIFY_EXPR, TREE_TYPE (new_var), new_var, x);
  3281. gimplify_and_add (x, ilist);
  3282. }
  3283. else if (TREE_CODE (TREE_TYPE (var)) == ARRAY_TYPE
  3284. && is_global_var (var))
  3285. {
  3286. tree ptype = build_pointer_type (TREE_TYPE (var)), t, t2;
  3287. new_var = lookup_decl (var, ctx);
  3288. t = maybe_lookup_decl_in_outer_ctx (var, ctx);
  3289. t = build_fold_addr_expr_loc (clause_loc, t);
  3290. t2 = builtin_decl_explicit (BUILT_IN_ASSUME_ALIGNED);
  3291. t = build_call_expr_loc (clause_loc, t2, 2, t,
  3292. omp_clause_aligned_alignment (c));
  3293. t = fold_convert_loc (clause_loc, ptype, t);
  3294. x = create_tmp_var (ptype);
  3295. t = build2 (MODIFY_EXPR, ptype, x, t);
  3296. gimplify_and_add (t, ilist);
  3297. t = build_simple_mem_ref_loc (clause_loc, x);
  3298. SET_DECL_VALUE_EXPR (new_var, t);
  3299. DECL_HAS_VALUE_EXPR_P (new_var) = 1;
  3300. }
  3301. continue;
  3302. default:
  3303. continue;
  3304. }
  3305. new_var = var = OMP_CLAUSE_DECL (c);
  3306. if (c_kind != OMP_CLAUSE_COPYIN)
  3307. new_var = lookup_decl (var, ctx);
  3308. if (c_kind == OMP_CLAUSE_SHARED || c_kind == OMP_CLAUSE_COPYIN)
  3309. {
  3310. if (pass != 0)
  3311. continue;
  3312. }
  3313. else if (is_variable_sized (var))
  3314. {
  3315. /* For variable sized types, we need to allocate the
  3316. actual storage here. Call alloca and store the
  3317. result in the pointer decl that we created elsewhere. */
  3318. if (pass == 0)
  3319. continue;
  3320. if (c_kind != OMP_CLAUSE_FIRSTPRIVATE || !is_task_ctx (ctx))
  3321. {
  3322. gcall *stmt;
  3323. tree tmp, atmp;
  3324. ptr = DECL_VALUE_EXPR (new_var);
  3325. gcc_assert (TREE_CODE (ptr) == INDIRECT_REF);
  3326. ptr = TREE_OPERAND (ptr, 0);
  3327. gcc_assert (DECL_P (ptr));
  3328. x = TYPE_SIZE_UNIT (TREE_TYPE (new_var));
  3329. /* void *tmp = __builtin_alloca */
  3330. atmp = builtin_decl_explicit (BUILT_IN_ALLOCA);
  3331. stmt = gimple_build_call (atmp, 1, x);
  3332. tmp = create_tmp_var_raw (ptr_type_node);
  3333. gimple_add_tmp_var (tmp);
  3334. gimple_call_set_lhs (stmt, tmp);
  3335. gimple_seq_add_stmt (ilist, stmt);
  3336. x = fold_convert_loc (clause_loc, TREE_TYPE (ptr), tmp);
  3337. gimplify_assign (ptr, x, ilist);
  3338. }
  3339. }
  3340. else if (is_reference (var))
  3341. {
  3342. /* For references that are being privatized for Fortran,
  3343. allocate new backing storage for the new pointer
  3344. variable. This allows us to avoid changing all the
  3345. code that expects a pointer to something that expects
  3346. a direct variable. */
  3347. if (pass == 0)
  3348. continue;
  3349. x = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (new_var)));
  3350. if (c_kind == OMP_CLAUSE_FIRSTPRIVATE && is_task_ctx (ctx))
  3351. {
  3352. x = build_receiver_ref (var, false, ctx);
  3353. x = build_fold_addr_expr_loc (clause_loc, x);
  3354. }
  3355. else if (TREE_CONSTANT (x))
  3356. {
  3357. /* For reduction in SIMD loop, defer adding the
  3358. initialization of the reference, because if we decide
  3359. to use SIMD array for it, the initilization could cause
  3360. expansion ICE. */
  3361. if (c_kind == OMP_CLAUSE_REDUCTION && is_simd)
  3362. x = NULL_TREE;
  3363. else
  3364. {
  3365. const char *name = NULL;
  3366. if (DECL_NAME (var))
  3367. name = IDENTIFIER_POINTER (DECL_NAME (new_var));
  3368. x = create_tmp_var_raw (TREE_TYPE (TREE_TYPE (new_var)),
  3369. name);
  3370. gimple_add_tmp_var (x);
  3371. TREE_ADDRESSABLE (x) = 1;
  3372. x = build_fold_addr_expr_loc (clause_loc, x);
  3373. }
  3374. }
  3375. else
  3376. {
  3377. tree atmp = builtin_decl_explicit (BUILT_IN_ALLOCA);
  3378. x = build_call_expr_loc (clause_loc, atmp, 1, x);
  3379. }
  3380. if (x)
  3381. {
  3382. x = fold_convert_loc (clause_loc, TREE_TYPE (new_var), x);
  3383. gimplify_assign (new_var, x, ilist);
  3384. }
  3385. new_var = build_simple_mem_ref_loc (clause_loc, new_var);
  3386. }
  3387. else if (c_kind == OMP_CLAUSE_REDUCTION
  3388. && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
  3389. {
  3390. if (pass == 0)
  3391. continue;
  3392. }
  3393. else if (pass != 0)
  3394. continue;
  3395. switch (OMP_CLAUSE_CODE (c))
  3396. {
  3397. case OMP_CLAUSE_SHARED:
  3398. /* Ignore shared directives in teams construct. */
  3399. if (gimple_code (ctx->stmt) == GIMPLE_OMP_TEAMS)
  3400. continue;
  3401. /* Shared global vars are just accessed directly. */
  3402. if (is_global_var (new_var))
  3403. break;
  3404. /* Set up the DECL_VALUE_EXPR for shared variables now. This
  3405. needs to be delayed until after fixup_child_record_type so
  3406. that we get the correct type during the dereference. */
  3407. by_ref = use_pointer_for_field (var, ctx);
  3408. x = build_receiver_ref (var, by_ref, ctx);
  3409. SET_DECL_VALUE_EXPR (new_var, x);
  3410. DECL_HAS_VALUE_EXPR_P (new_var) = 1;
  3411. /* ??? If VAR is not passed by reference, and the variable
  3412. hasn't been initialized yet, then we'll get a warning for
  3413. the store into the omp_data_s structure. Ideally, we'd be
  3414. able to notice this and not store anything at all, but
  3415. we're generating code too early. Suppress the warning. */
  3416. if (!by_ref)
  3417. TREE_NO_WARNING (var) = 1;
  3418. break;
  3419. case OMP_CLAUSE_LASTPRIVATE:
  3420. if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
  3421. break;
  3422. /* FALLTHRU */
  3423. case OMP_CLAUSE_PRIVATE:
  3424. if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_PRIVATE)
  3425. x = build_outer_var_ref (var, ctx);
  3426. else if (OMP_CLAUSE_PRIVATE_OUTER_REF (c))
  3427. {
  3428. if (is_task_ctx (ctx))
  3429. x = build_receiver_ref (var, false, ctx);
  3430. else
  3431. x = build_outer_var_ref (var, ctx);
  3432. }
  3433. else
  3434. x = NULL;
  3435. do_private:
  3436. tree nx;
  3437. nx = lang_hooks.decls.omp_clause_default_ctor (c, new_var, x);
  3438. if (is_simd)
  3439. {
  3440. tree y = lang_hooks.decls.omp_clause_dtor (c, new_var);
  3441. if ((TREE_ADDRESSABLE (new_var) || nx || y
  3442. || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE)
  3443. && lower_rec_simd_input_clauses (new_var, ctx, max_vf,
  3444. idx, lane, ivar, lvar))
  3445. {
  3446. if (nx)
  3447. x = lang_hooks.decls.omp_clause_default_ctor
  3448. (c, unshare_expr (ivar), x);
  3449. if (nx && x)
  3450. gimplify_and_add (x, &llist[0]);
  3451. if (y)
  3452. {
  3453. y = lang_hooks.decls.omp_clause_dtor (c, ivar);
  3454. if (y)
  3455. {
  3456. gimple_seq tseq = NULL;
  3457. dtor = y;
  3458. gimplify_stmt (&dtor, &tseq);
  3459. gimple_seq_add_seq (&llist[1], tseq);
  3460. }
  3461. }
  3462. break;
  3463. }
  3464. }
  3465. if (nx)
  3466. gimplify_and_add (nx, ilist);
  3467. /* FALLTHRU */
  3468. do_dtor:
  3469. x = lang_hooks.decls.omp_clause_dtor (c, new_var);
  3470. if (x)
  3471. {
  3472. gimple_seq tseq = NULL;
  3473. dtor = x;
  3474. gimplify_stmt (&dtor, &tseq);
  3475. gimple_seq_add_seq (dlist, tseq);
  3476. }
  3477. break;
  3478. case OMP_CLAUSE_LINEAR:
  3479. if (!OMP_CLAUSE_LINEAR_NO_COPYIN (c))
  3480. goto do_firstprivate;
  3481. if (OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
  3482. x = NULL;
  3483. else
  3484. x = build_outer_var_ref (var, ctx);
  3485. goto do_private;
  3486. case OMP_CLAUSE_FIRSTPRIVATE:
  3487. if (is_task_ctx (ctx))
  3488. {
  3489. if (is_reference (var) || is_variable_sized (var))
  3490. goto do_dtor;
  3491. else if (is_global_var (maybe_lookup_decl_in_outer_ctx (var,
  3492. ctx))
  3493. || use_pointer_for_field (var, NULL))
  3494. {
  3495. x = build_receiver_ref (var, false, ctx);
  3496. SET_DECL_VALUE_EXPR (new_var, x);
  3497. DECL_HAS_VALUE_EXPR_P (new_var) = 1;
  3498. goto do_dtor;
  3499. }
  3500. }
  3501. do_firstprivate:
  3502. x = build_outer_var_ref (var, ctx);
  3503. if (is_simd)
  3504. {
  3505. if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
  3506. && gimple_omp_for_combined_into_p (ctx->stmt))
  3507. {
  3508. tree t = OMP_CLAUSE_LINEAR_STEP (c);
  3509. tree stept = TREE_TYPE (t);
  3510. tree ct = find_omp_clause (clauses,
  3511. OMP_CLAUSE__LOOPTEMP_);
  3512. gcc_assert (ct);
  3513. tree l = OMP_CLAUSE_DECL (ct);
  3514. tree n1 = fd->loop.n1;
  3515. tree step = fd->loop.step;
  3516. tree itype = TREE_TYPE (l);
  3517. if (POINTER_TYPE_P (itype))
  3518. itype = signed_type_for (itype);
  3519. l = fold_build2 (MINUS_EXPR, itype, l, n1);
  3520. if (TYPE_UNSIGNED (itype)
  3521. && fd->loop.cond_code == GT_EXPR)
  3522. l = fold_build2 (TRUNC_DIV_EXPR, itype,
  3523. fold_build1 (NEGATE_EXPR, itype, l),
  3524. fold_build1 (NEGATE_EXPR,
  3525. itype, step));
  3526. else
  3527. l = fold_build2 (TRUNC_DIV_EXPR, itype, l, step);
  3528. t = fold_build2 (MULT_EXPR, stept,
  3529. fold_convert (stept, l), t);
  3530. if (OMP_CLAUSE_LINEAR_ARRAY (c))
  3531. {
  3532. x = lang_hooks.decls.omp_clause_linear_ctor
  3533. (c, new_var, x, t);
  3534. gimplify_and_add (x, ilist);
  3535. goto do_dtor;
  3536. }
  3537. if (POINTER_TYPE_P (TREE_TYPE (x)))
  3538. x = fold_build2 (POINTER_PLUS_EXPR,
  3539. TREE_TYPE (x), x, t);
  3540. else
  3541. x = fold_build2 (PLUS_EXPR, TREE_TYPE (x), x, t);
  3542. }
  3543. if ((OMP_CLAUSE_CODE (c) != OMP_CLAUSE_LINEAR
  3544. || TREE_ADDRESSABLE (new_var))
  3545. && lower_rec_simd_input_clauses (new_var, ctx, max_vf,
  3546. idx, lane, ivar, lvar))
  3547. {
  3548. if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR)
  3549. {
  3550. tree iv = create_tmp_var (TREE_TYPE (new_var));
  3551. x = lang_hooks.decls.omp_clause_copy_ctor (c, iv, x);
  3552. gimplify_and_add (x, ilist);
  3553. gimple_stmt_iterator gsi
  3554. = gsi_start_1 (gimple_omp_body_ptr (ctx->stmt));
  3555. gassign *g
  3556. = gimple_build_assign (unshare_expr (lvar), iv);
  3557. gsi_insert_before_without_update (&gsi, g,
  3558. GSI_SAME_STMT);
  3559. tree t = OMP_CLAUSE_LINEAR_STEP (c);
  3560. enum tree_code code = PLUS_EXPR;
  3561. if (POINTER_TYPE_P (TREE_TYPE (new_var)))
  3562. code = POINTER_PLUS_EXPR;
  3563. g = gimple_build_assign (iv, code, iv, t);
  3564. gsi_insert_before_without_update (&gsi, g,
  3565. GSI_SAME_STMT);
  3566. break;
  3567. }
  3568. x = lang_hooks.decls.omp_clause_copy_ctor
  3569. (c, unshare_expr (ivar), x);
  3570. gimplify_and_add (x, &llist[0]);
  3571. x = lang_hooks.decls.omp_clause_dtor (c, ivar);
  3572. if (x)
  3573. {
  3574. gimple_seq tseq = NULL;
  3575. dtor = x;
  3576. gimplify_stmt (&dtor, &tseq);
  3577. gimple_seq_add_seq (&llist[1], tseq);
  3578. }
  3579. break;
  3580. }
  3581. }
  3582. x = lang_hooks.decls.omp_clause_copy_ctor (c, new_var, x);
  3583. gimplify_and_add (x, ilist);
  3584. goto do_dtor;
  3585. case OMP_CLAUSE__LOOPTEMP_:
  3586. gcc_assert (is_parallel_ctx (ctx));
  3587. x = build_outer_var_ref (var, ctx);
  3588. x = build2 (MODIFY_EXPR, TREE_TYPE (new_var), new_var, x);
  3589. gimplify_and_add (x, ilist);
  3590. break;
  3591. case OMP_CLAUSE_COPYIN:
  3592. by_ref = use_pointer_for_field (var, NULL);
  3593. x = build_receiver_ref (var, by_ref, ctx);
  3594. x = lang_hooks.decls.omp_clause_assign_op (c, new_var, x);
  3595. append_to_statement_list (x, &copyin_seq);
  3596. copyin_by_ref |= by_ref;
  3597. break;
  3598. case OMP_CLAUSE_REDUCTION:
  3599. if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
  3600. {
  3601. tree placeholder = OMP_CLAUSE_REDUCTION_PLACEHOLDER (c);
  3602. gimple tseq;
  3603. x = build_outer_var_ref (var, ctx);
  3604. if (is_reference (var)
  3605. && !useless_type_conversion_p (TREE_TYPE (placeholder),
  3606. TREE_TYPE (x)))
  3607. x = build_fold_addr_expr_loc (clause_loc, x);
  3608. SET_DECL_VALUE_EXPR (placeholder, x);
  3609. DECL_HAS_VALUE_EXPR_P (placeholder) = 1;
  3610. tree new_vard = new_var;
  3611. if (is_reference (var))
  3612. {
  3613. gcc_assert (TREE_CODE (new_var) == MEM_REF);
  3614. new_vard = TREE_OPERAND (new_var, 0);
  3615. gcc_assert (DECL_P (new_vard));
  3616. }
  3617. if (is_simd
  3618. && lower_rec_simd_input_clauses (new_var, ctx, max_vf,
  3619. idx, lane, ivar, lvar))
  3620. {
  3621. if (new_vard == new_var)
  3622. {
  3623. gcc_assert (DECL_VALUE_EXPR (new_var) == lvar);
  3624. SET_DECL_VALUE_EXPR (new_var, ivar);
  3625. }
  3626. else
  3627. {
  3628. SET_DECL_VALUE_EXPR (new_vard,
  3629. build_fold_addr_expr (ivar));
  3630. DECL_HAS_VALUE_EXPR_P (new_vard) = 1;
  3631. }
  3632. x = lang_hooks.decls.omp_clause_default_ctor
  3633. (c, unshare_expr (ivar),
  3634. build_outer_var_ref (var, ctx));
  3635. if (x)
  3636. gimplify_and_add (x, &llist[0]);
  3637. if (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c))
  3638. {
  3639. tseq = OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c);
  3640. lower_omp (&tseq, ctx);
  3641. gimple_seq_add_seq (&llist[0], tseq);
  3642. }
  3643. OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c) = NULL;
  3644. tseq = OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c);
  3645. lower_omp (&tseq, ctx);
  3646. gimple_seq_add_seq (&llist[1], tseq);
  3647. OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c) = NULL;
  3648. DECL_HAS_VALUE_EXPR_P (placeholder) = 0;
  3649. if (new_vard == new_var)
  3650. SET_DECL_VALUE_EXPR (new_var, lvar);
  3651. else
  3652. SET_DECL_VALUE_EXPR (new_vard,
  3653. build_fold_addr_expr (lvar));
  3654. x = lang_hooks.decls.omp_clause_dtor (c, ivar);
  3655. if (x)
  3656. {
  3657. tseq = NULL;
  3658. dtor = x;
  3659. gimplify_stmt (&dtor, &tseq);
  3660. gimple_seq_add_seq (&llist[1], tseq);
  3661. }
  3662. break;
  3663. }
  3664. /* If this is a reference to constant size reduction var
  3665. with placeholder, we haven't emitted the initializer
  3666. for it because it is undesirable if SIMD arrays are used.
  3667. But if they aren't used, we need to emit the deferred
  3668. initialization now. */
  3669. else if (is_reference (var) && is_simd)
  3670. handle_simd_reference (clause_loc, new_vard, ilist);
  3671. x = lang_hooks.decls.omp_clause_default_ctor
  3672. (c, unshare_expr (new_var),
  3673. build_outer_var_ref (var, ctx));
  3674. if (x)
  3675. gimplify_and_add (x, ilist);
  3676. if (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c))
  3677. {
  3678. tseq = OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c);
  3679. lower_omp (&tseq, ctx);
  3680. gimple_seq_add_seq (ilist, tseq);
  3681. }
  3682. OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c) = NULL;
  3683. if (is_simd)
  3684. {
  3685. tseq = OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c);
  3686. lower_omp (&tseq, ctx);
  3687. gimple_seq_add_seq (dlist, tseq);
  3688. OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c) = NULL;
  3689. }
  3690. DECL_HAS_VALUE_EXPR_P (placeholder) = 0;
  3691. goto do_dtor;
  3692. }
  3693. else
  3694. {
  3695. x = omp_reduction_init (c, TREE_TYPE (new_var));
  3696. gcc_assert (TREE_CODE (TREE_TYPE (new_var)) != ARRAY_TYPE);
  3697. enum tree_code code = OMP_CLAUSE_REDUCTION_CODE (c);
  3698. /* reduction(-:var) sums up the partial results, so it
  3699. acts identically to reduction(+:var). */
  3700. if (code == MINUS_EXPR)
  3701. code = PLUS_EXPR;
  3702. tree new_vard = new_var;
  3703. if (is_simd && is_reference (var))
  3704. {
  3705. gcc_assert (TREE_CODE (new_var) == MEM_REF);
  3706. new_vard = TREE_OPERAND (new_var, 0);
  3707. gcc_assert (DECL_P (new_vard));
  3708. }
  3709. if (is_simd
  3710. && lower_rec_simd_input_clauses (new_var, ctx, max_vf,
  3711. idx, lane, ivar, lvar))
  3712. {
  3713. tree ref = build_outer_var_ref (var, ctx);
  3714. gimplify_assign (unshare_expr (ivar), x, &llist[0]);
  3715. x = build2 (code, TREE_TYPE (ref), ref, ivar);
  3716. ref = build_outer_var_ref (var, ctx);
  3717. gimplify_assign (ref, x, &llist[1]);
  3718. if (new_vard != new_var)
  3719. {
  3720. SET_DECL_VALUE_EXPR (new_vard,
  3721. build_fold_addr_expr (lvar));
  3722. DECL_HAS_VALUE_EXPR_P (new_vard) = 1;
  3723. }
  3724. }
  3725. else
  3726. {
  3727. if (is_reference (var) && is_simd)
  3728. handle_simd_reference (clause_loc, new_vard, ilist);
  3729. gimplify_assign (new_var, x, ilist);
  3730. if (is_simd)
  3731. {
  3732. tree ref = build_outer_var_ref (var, ctx);
  3733. x = build2 (code, TREE_TYPE (ref), ref, new_var);
  3734. ref = build_outer_var_ref (var, ctx);
  3735. gimplify_assign (ref, x, dlist);
  3736. }
  3737. }
  3738. }
  3739. break;
  3740. default:
  3741. gcc_unreachable ();
  3742. }
  3743. }
  3744. }
  3745. if (lane)
  3746. {
  3747. tree uid = create_tmp_var (ptr_type_node, "simduid");
  3748. /* Don't want uninit warnings on simduid, it is always uninitialized,
  3749. but we use it not for the value, but for the DECL_UID only. */
  3750. TREE_NO_WARNING (uid) = 1;
  3751. gimple g
  3752. = gimple_build_call_internal (IFN_GOMP_SIMD_LANE, 1, uid);
  3753. gimple_call_set_lhs (g, lane);
  3754. gimple_stmt_iterator gsi = gsi_start_1 (gimple_omp_body_ptr (ctx->stmt));
  3755. gsi_insert_before_without_update (&gsi, g, GSI_SAME_STMT);
  3756. c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE__SIMDUID_);
  3757. OMP_CLAUSE__SIMDUID__DECL (c) = uid;
  3758. OMP_CLAUSE_CHAIN (c) = gimple_omp_for_clauses (ctx->stmt);
  3759. gimple_omp_for_set_clauses (ctx->stmt, c);
  3760. g = gimple_build_assign (lane, INTEGER_CST,
  3761. build_int_cst (unsigned_type_node, 0));
  3762. gimple_seq_add_stmt (ilist, g);
  3763. for (int i = 0; i < 2; i++)
  3764. if (llist[i])
  3765. {
  3766. tree vf = create_tmp_var (unsigned_type_node);
  3767. g = gimple_build_call_internal (IFN_GOMP_SIMD_VF, 1, uid);
  3768. gimple_call_set_lhs (g, vf);
  3769. gimple_seq *seq = i == 0 ? ilist : dlist;
  3770. gimple_seq_add_stmt (seq, g);
  3771. tree t = build_int_cst (unsigned_type_node, 0);
  3772. g = gimple_build_assign (idx, INTEGER_CST, t);
  3773. gimple_seq_add_stmt (seq, g);
  3774. tree body = create_artificial_label (UNKNOWN_LOCATION);
  3775. tree header = create_artificial_label (UNKNOWN_LOCATION);
  3776. tree end = create_artificial_label (UNKNOWN_LOCATION);
  3777. gimple_seq_add_stmt (seq, gimple_build_goto (header));
  3778. gimple_seq_add_stmt (seq, gimple_build_label (body));
  3779. gimple_seq_add_seq (seq, llist[i]);
  3780. t = build_int_cst (unsigned_type_node, 1);
  3781. g = gimple_build_assign (idx, PLUS_EXPR, idx, t);
  3782. gimple_seq_add_stmt (seq, g);
  3783. gimple_seq_add_stmt (seq, gimple_build_label (header));
  3784. g = gimple_build_cond (LT_EXPR, idx, vf, body, end);
  3785. gimple_seq_add_stmt (seq, g);
  3786. gimple_seq_add_stmt (seq, gimple_build_label (end));
  3787. }
  3788. }
  3789. /* The copyin sequence is not to be executed by the main thread, since
  3790. that would result in self-copies. Perhaps not visible to scalars,
  3791. but it certainly is to C++ operator=. */
  3792. if (copyin_seq)
  3793. {
  3794. x = build_call_expr (builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM),
  3795. 0);
  3796. x = build2 (NE_EXPR, boolean_type_node, x,
  3797. build_int_cst (TREE_TYPE (x), 0));
  3798. x = build3 (COND_EXPR, void_type_node, x, copyin_seq, NULL);
  3799. gimplify_and_add (x, ilist);
  3800. }
  3801. /* If any copyin variable is passed by reference, we must ensure the
  3802. master thread doesn't modify it before it is copied over in all
  3803. threads. Similarly for variables in both firstprivate and
  3804. lastprivate clauses we need to ensure the lastprivate copying
  3805. happens after firstprivate copying in all threads. And similarly
  3806. for UDRs if initializer expression refers to omp_orig. */
  3807. if (copyin_by_ref || lastprivate_firstprivate || reduction_omp_orig_ref)
  3808. {
  3809. /* Don't add any barrier for #pragma omp simd or
  3810. #pragma omp distribute. */
  3811. if (gimple_code (ctx->stmt) != GIMPLE_OMP_FOR
  3812. || gimple_omp_for_kind (ctx->stmt) == GF_OMP_FOR_KIND_FOR)
  3813. gimple_seq_add_stmt (ilist, build_omp_barrier (NULL_TREE));
  3814. }
  3815. /* If max_vf is non-zero, then we can use only a vectorization factor
  3816. up to the max_vf we chose. So stick it into the safelen clause. */
  3817. if (max_vf)
  3818. {
  3819. tree c = find_omp_clause (gimple_omp_for_clauses (ctx->stmt),
  3820. OMP_CLAUSE_SAFELEN);
  3821. if (c == NULL_TREE
  3822. || (TREE_CODE (OMP_CLAUSE_SAFELEN_EXPR (c)) == INTEGER_CST
  3823. && compare_tree_int (OMP_CLAUSE_SAFELEN_EXPR (c),
  3824. max_vf) == 1))
  3825. {
  3826. c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_SAFELEN);
  3827. OMP_CLAUSE_SAFELEN_EXPR (c) = build_int_cst (integer_type_node,
  3828. max_vf);
  3829. OMP_CLAUSE_CHAIN (c) = gimple_omp_for_clauses (ctx->stmt);
  3830. gimple_omp_for_set_clauses (ctx->stmt, c);
  3831. }
  3832. }
  3833. }
  3834. /* Generate code to implement the LASTPRIVATE clauses. This is used for
  3835. both parallel and workshare constructs. PREDICATE may be NULL if it's
  3836. always true. */
  3837. static void
  3838. lower_lastprivate_clauses (tree clauses, tree predicate, gimple_seq *stmt_list,
  3839. omp_context *ctx)
  3840. {
  3841. tree x, c, label = NULL, orig_clauses = clauses;
  3842. bool par_clauses = false;
  3843. tree simduid = NULL, lastlane = NULL;
  3844. /* Early exit if there are no lastprivate or linear clauses. */
  3845. for (; clauses ; clauses = OMP_CLAUSE_CHAIN (clauses))
  3846. if (OMP_CLAUSE_CODE (clauses) == OMP_CLAUSE_LASTPRIVATE
  3847. || (OMP_CLAUSE_CODE (clauses) == OMP_CLAUSE_LINEAR
  3848. && !OMP_CLAUSE_LINEAR_NO_COPYOUT (clauses)))
  3849. break;
  3850. if (clauses == NULL)
  3851. {
  3852. /* If this was a workshare clause, see if it had been combined
  3853. with its parallel. In that case, look for the clauses on the
  3854. parallel statement itself. */
  3855. if (is_parallel_ctx (ctx))
  3856. return;
  3857. ctx = ctx->outer;
  3858. if (ctx == NULL || !is_parallel_ctx (ctx))
  3859. return;
  3860. clauses = find_omp_clause (gimple_omp_parallel_clauses (ctx->stmt),
  3861. OMP_CLAUSE_LASTPRIVATE);
  3862. if (clauses == NULL)
  3863. return;
  3864. par_clauses = true;
  3865. }
  3866. if (predicate)
  3867. {
  3868. gcond *stmt;
  3869. tree label_true, arm1, arm2;
  3870. label = create_artificial_label (UNKNOWN_LOCATION);
  3871. label_true = create_artificial_label (UNKNOWN_LOCATION);
  3872. arm1 = TREE_OPERAND (predicate, 0);
  3873. arm2 = TREE_OPERAND (predicate, 1);
  3874. gimplify_expr (&arm1, stmt_list, NULL, is_gimple_val, fb_rvalue);
  3875. gimplify_expr (&arm2, stmt_list, NULL, is_gimple_val, fb_rvalue);
  3876. stmt = gimple_build_cond (TREE_CODE (predicate), arm1, arm2,
  3877. label_true, label);
  3878. gimple_seq_add_stmt (stmt_list, stmt);
  3879. gimple_seq_add_stmt (stmt_list, gimple_build_label (label_true));
  3880. }
  3881. if (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
  3882. && gimple_omp_for_kind (ctx->stmt) & GF_OMP_FOR_SIMD)
  3883. {
  3884. simduid = find_omp_clause (orig_clauses, OMP_CLAUSE__SIMDUID_);
  3885. if (simduid)
  3886. simduid = OMP_CLAUSE__SIMDUID__DECL (simduid);
  3887. }
  3888. for (c = clauses; c ;)
  3889. {
  3890. tree var, new_var;
  3891. location_t clause_loc = OMP_CLAUSE_LOCATION (c);
  3892. if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
  3893. || (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
  3894. && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)))
  3895. {
  3896. var = OMP_CLAUSE_DECL (c);
  3897. new_var = lookup_decl (var, ctx);
  3898. if (simduid && DECL_HAS_VALUE_EXPR_P (new_var))
  3899. {
  3900. tree val = DECL_VALUE_EXPR (new_var);
  3901. if (TREE_CODE (val) == ARRAY_REF
  3902. && VAR_P (TREE_OPERAND (val, 0))
  3903. && lookup_attribute ("omp simd array",
  3904. DECL_ATTRIBUTES (TREE_OPERAND (val,
  3905. 0))))
  3906. {
  3907. if (lastlane == NULL)
  3908. {
  3909. lastlane = create_tmp_var (unsigned_type_node);
  3910. gcall *g
  3911. = gimple_build_call_internal (IFN_GOMP_SIMD_LAST_LANE,
  3912. 2, simduid,
  3913. TREE_OPERAND (val, 1));
  3914. gimple_call_set_lhs (g, lastlane);
  3915. gimple_seq_add_stmt (stmt_list, g);
  3916. }
  3917. new_var = build4 (ARRAY_REF, TREE_TYPE (val),
  3918. TREE_OPERAND (val, 0), lastlane,
  3919. NULL_TREE, NULL_TREE);
  3920. }
  3921. }
  3922. if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
  3923. && OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c))
  3924. {
  3925. lower_omp (&OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c), ctx);
  3926. gimple_seq_add_seq (stmt_list,
  3927. OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c));
  3928. OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c) = NULL;
  3929. }
  3930. else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
  3931. && OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c))
  3932. {
  3933. lower_omp (&OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c), ctx);
  3934. gimple_seq_add_seq (stmt_list,
  3935. OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c));
  3936. OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c) = NULL;
  3937. }
  3938. x = build_outer_var_ref (var, ctx);
  3939. if (is_reference (var))
  3940. new_var = build_simple_mem_ref_loc (clause_loc, new_var);
  3941. x = lang_hooks.decls.omp_clause_assign_op (c, x, new_var);
  3942. gimplify_and_add (x, stmt_list);
  3943. }
  3944. c = OMP_CLAUSE_CHAIN (c);
  3945. if (c == NULL && !par_clauses)
  3946. {
  3947. /* If this was a workshare clause, see if it had been combined
  3948. with its parallel. In that case, continue looking for the
  3949. clauses also on the parallel statement itself. */
  3950. if (is_parallel_ctx (ctx))
  3951. break;
  3952. ctx = ctx->outer;
  3953. if (ctx == NULL || !is_parallel_ctx (ctx))
  3954. break;
  3955. c = find_omp_clause (gimple_omp_parallel_clauses (ctx->stmt),
  3956. OMP_CLAUSE_LASTPRIVATE);
  3957. par_clauses = true;
  3958. }
  3959. }
  3960. if (label)
  3961. gimple_seq_add_stmt (stmt_list, gimple_build_label (label));
  3962. }
  3963. static void
  3964. oacc_lower_reduction_var_helper (gimple_seq *stmt_seqp, omp_context *ctx,
  3965. tree tid, tree var, tree new_var)
  3966. {
  3967. /* The atomic add at the end of the sum creates unnecessary
  3968. write contention on accelerators. To work around this,
  3969. create an array to store the partial reductions. Later, in
  3970. lower_omp_for (for openacc), the values of array will be
  3971. combined. */
  3972. tree t = NULL_TREE, array, x;
  3973. tree type = get_base_type (var);
  3974. gimple stmt;
  3975. /* Now insert the partial reductions into the array. */
  3976. /* Find the reduction array. */
  3977. tree ptype = build_pointer_type (type);
  3978. t = lookup_oacc_reduction (oacc_get_reduction_array_id (var), ctx);
  3979. t = build_receiver_ref (t, false, ctx->outer);
  3980. array = create_tmp_var (ptype);
  3981. gimplify_assign (array, t, stmt_seqp);
  3982. tree ptr = create_tmp_var (TREE_TYPE (array));
  3983. /* Find the reduction array. */
  3984. /* testing a unary conversion. */
  3985. tree offset = create_tmp_var (sizetype);
  3986. gimplify_assign (offset, TYPE_SIZE_UNIT (type),
  3987. stmt_seqp);
  3988. t = create_tmp_var (sizetype);
  3989. gimplify_assign (t, unshare_expr (fold_build1 (NOP_EXPR, sizetype, tid)),
  3990. stmt_seqp);
  3991. stmt = gimple_build_assign (offset, MULT_EXPR, offset, t);
  3992. gimple_seq_add_stmt (stmt_seqp, stmt);
  3993. /* Offset expression. Does the POINTER_PLUS_EXPR take care
  3994. of adding sizeof(var) to the array? */
  3995. ptr = create_tmp_var (ptype);
  3996. stmt = gimple_build_assign (unshare_expr (ptr), POINTER_PLUS_EXPR, array,
  3997. offset);
  3998. gimple_seq_add_stmt (stmt_seqp, stmt);
  3999. /* Move the local sum to gfc$sum[i]. */
  4000. x = unshare_expr (build_simple_mem_ref (ptr));
  4001. stmt = gimplify_assign (x, new_var, stmt_seqp);
  4002. }
  4003. /* Generate code to implement the REDUCTION clauses. */
  4004. static void
  4005. lower_reduction_clauses (tree clauses, gimple_seq *stmt_seqp, omp_context *ctx)
  4006. {
  4007. gimple_seq sub_seq = NULL;
  4008. gimple stmt;
  4009. tree x, c, tid = NULL_TREE;
  4010. int count = 0;
  4011. /* SIMD reductions are handled in lower_rec_input_clauses. */
  4012. if (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
  4013. && gimple_omp_for_kind (ctx->stmt) & GF_OMP_FOR_SIMD)
  4014. return;
  4015. /* First see if there is exactly one reduction clause. Use OMP_ATOMIC
  4016. update in that case, otherwise use a lock. */
  4017. for (c = clauses; c && count < 2; c = OMP_CLAUSE_CHAIN (c))
  4018. if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION)
  4019. {
  4020. if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
  4021. {
  4022. /* Never use OMP_ATOMIC for array reductions or UDRs. */
  4023. count = -1;
  4024. break;
  4025. }
  4026. count++;
  4027. }
  4028. if (count == 0)
  4029. return;
  4030. /* Initialize thread info for OpenACC. */
  4031. if (is_gimple_omp_oacc (ctx->stmt))
  4032. {
  4033. /* Get the current thread id. */
  4034. tree call = builtin_decl_explicit (BUILT_IN_GOACC_GET_THREAD_NUM);
  4035. tid = create_tmp_var (TREE_TYPE (TREE_TYPE (call)));
  4036. gimple stmt = gimple_build_call (call, 0);
  4037. gimple_call_set_lhs (stmt, tid);
  4038. gimple_seq_add_stmt (stmt_seqp, stmt);
  4039. }
  4040. for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
  4041. {
  4042. tree var, ref, new_var;
  4043. enum tree_code code;
  4044. location_t clause_loc = OMP_CLAUSE_LOCATION (c);
  4045. if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION)
  4046. continue;
  4047. var = OMP_CLAUSE_DECL (c);
  4048. new_var = lookup_decl (var, ctx);
  4049. if (is_reference (var))
  4050. new_var = build_simple_mem_ref_loc (clause_loc, new_var);
  4051. ref = build_outer_var_ref (var, ctx);
  4052. code = OMP_CLAUSE_REDUCTION_CODE (c);
  4053. /* reduction(-:var) sums up the partial results, so it acts
  4054. identically to reduction(+:var). */
  4055. if (code == MINUS_EXPR)
  4056. code = PLUS_EXPR;
  4057. if (is_gimple_omp_oacc (ctx->stmt))
  4058. {
  4059. gcc_checking_assert (!OMP_CLAUSE_REDUCTION_PLACEHOLDER (c));
  4060. oacc_lower_reduction_var_helper (stmt_seqp, ctx, tid, var, new_var);
  4061. }
  4062. else if (count == 1)
  4063. {
  4064. tree addr = build_fold_addr_expr_loc (clause_loc, ref);
  4065. addr = save_expr (addr);
  4066. ref = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (addr)), addr);
  4067. x = fold_build2_loc (clause_loc, code, TREE_TYPE (ref), ref, new_var);
  4068. x = build2 (OMP_ATOMIC, void_type_node, addr, x);
  4069. gimplify_and_add (x, stmt_seqp);
  4070. return;
  4071. }
  4072. else if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
  4073. {
  4074. tree placeholder = OMP_CLAUSE_REDUCTION_PLACEHOLDER (c);
  4075. if (is_reference (var)
  4076. && !useless_type_conversion_p (TREE_TYPE (placeholder),
  4077. TREE_TYPE (ref)))
  4078. ref = build_fold_addr_expr_loc (clause_loc, ref);
  4079. SET_DECL_VALUE_EXPR (placeholder, ref);
  4080. DECL_HAS_VALUE_EXPR_P (placeholder) = 1;
  4081. lower_omp (&OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c), ctx);
  4082. gimple_seq_add_seq (&sub_seq, OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c));
  4083. OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c) = NULL;
  4084. OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) = NULL;
  4085. }
  4086. else
  4087. {
  4088. x = build2 (code, TREE_TYPE (ref), ref, new_var);
  4089. ref = build_outer_var_ref (var, ctx);
  4090. gimplify_assign (ref, x, &sub_seq);
  4091. }
  4092. }
  4093. if (is_gimple_omp_oacc (ctx->stmt))
  4094. return;
  4095. stmt = gimple_build_call (builtin_decl_explicit (BUILT_IN_GOMP_ATOMIC_START),
  4096. 0);
  4097. gimple_seq_add_stmt (stmt_seqp, stmt);
  4098. gimple_seq_add_seq (stmt_seqp, sub_seq);
  4099. stmt = gimple_build_call (builtin_decl_explicit (BUILT_IN_GOMP_ATOMIC_END),
  4100. 0);
  4101. gimple_seq_add_stmt (stmt_seqp, stmt);
  4102. }
  4103. /* Generate code to implement the COPYPRIVATE clauses. */
  4104. static void
  4105. lower_copyprivate_clauses (tree clauses, gimple_seq *slist, gimple_seq *rlist,
  4106. omp_context *ctx)
  4107. {
  4108. tree c;
  4109. for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
  4110. {
  4111. tree var, new_var, ref, x;
  4112. bool by_ref;
  4113. location_t clause_loc = OMP_CLAUSE_LOCATION (c);
  4114. if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_COPYPRIVATE)
  4115. continue;
  4116. var = OMP_CLAUSE_DECL (c);
  4117. by_ref = use_pointer_for_field (var, NULL);
  4118. ref = build_sender_ref (var, ctx);
  4119. x = new_var = lookup_decl_in_outer_ctx (var, ctx);
  4120. if (by_ref)
  4121. {
  4122. x = build_fold_addr_expr_loc (clause_loc, new_var);
  4123. x = fold_convert_loc (clause_loc, TREE_TYPE (ref), x);
  4124. }
  4125. gimplify_assign (ref, x, slist);
  4126. ref = build_receiver_ref (var, false, ctx);
  4127. if (by_ref)
  4128. {
  4129. ref = fold_convert_loc (clause_loc,
  4130. build_pointer_type (TREE_TYPE (new_var)),
  4131. ref);
  4132. ref = build_fold_indirect_ref_loc (clause_loc, ref);
  4133. }
  4134. if (is_reference (var))
  4135. {
  4136. ref = fold_convert_loc (clause_loc, TREE_TYPE (new_var), ref);
  4137. ref = build_simple_mem_ref_loc (clause_loc, ref);
  4138. new_var = build_simple_mem_ref_loc (clause_loc, new_var);
  4139. }
  4140. x = lang_hooks.decls.omp_clause_assign_op (c, new_var, ref);
  4141. gimplify_and_add (x, rlist);
  4142. }
  4143. }
  4144. /* Generate code to implement the clauses, FIRSTPRIVATE, COPYIN, LASTPRIVATE,
  4145. and REDUCTION from the sender (aka parent) side. */
  4146. static void
  4147. lower_send_clauses (tree clauses, gimple_seq *ilist, gimple_seq *olist,
  4148. omp_context *ctx)
  4149. {
  4150. tree c;
  4151. for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
  4152. {
  4153. tree val, ref, x, var;
  4154. bool by_ref, do_in = false, do_out = false;
  4155. location_t clause_loc = OMP_CLAUSE_LOCATION (c);
  4156. switch (OMP_CLAUSE_CODE (c))
  4157. {
  4158. case OMP_CLAUSE_PRIVATE:
  4159. if (OMP_CLAUSE_PRIVATE_OUTER_REF (c))
  4160. break;
  4161. continue;
  4162. case OMP_CLAUSE_FIRSTPRIVATE:
  4163. case OMP_CLAUSE_COPYIN:
  4164. case OMP_CLAUSE_LASTPRIVATE:
  4165. case OMP_CLAUSE_REDUCTION:
  4166. case OMP_CLAUSE__LOOPTEMP_:
  4167. break;
  4168. default:
  4169. continue;
  4170. }
  4171. val = OMP_CLAUSE_DECL (c);
  4172. var = lookup_decl_in_outer_ctx (val, ctx);
  4173. if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_COPYIN
  4174. && is_global_var (var))
  4175. continue;
  4176. if (is_variable_sized (val))
  4177. continue;
  4178. by_ref = use_pointer_for_field (val, NULL);
  4179. switch (OMP_CLAUSE_CODE (c))
  4180. {
  4181. case OMP_CLAUSE_PRIVATE:
  4182. case OMP_CLAUSE_FIRSTPRIVATE:
  4183. case OMP_CLAUSE_COPYIN:
  4184. case OMP_CLAUSE__LOOPTEMP_:
  4185. do_in = true;
  4186. break;
  4187. case OMP_CLAUSE_LASTPRIVATE:
  4188. if (by_ref || is_reference (val))
  4189. {
  4190. if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
  4191. continue;
  4192. do_in = true;
  4193. }
  4194. else
  4195. {
  4196. do_out = true;
  4197. if (lang_hooks.decls.omp_private_outer_ref (val))
  4198. do_in = true;
  4199. }
  4200. break;
  4201. case OMP_CLAUSE_REDUCTION:
  4202. do_in = true;
  4203. do_out = !(by_ref || is_reference (val));
  4204. break;
  4205. default:
  4206. gcc_unreachable ();
  4207. }
  4208. if (do_in)
  4209. {
  4210. ref = build_sender_ref (val, ctx);
  4211. x = by_ref ? build_fold_addr_expr_loc (clause_loc, var) : var;
  4212. gimplify_assign (ref, x, ilist);
  4213. if (is_task_ctx (ctx))
  4214. DECL_ABSTRACT_ORIGIN (TREE_OPERAND (ref, 1)) = NULL;
  4215. }
  4216. if (do_out)
  4217. {
  4218. ref = build_sender_ref (val, ctx);
  4219. gimplify_assign (var, ref, olist);
  4220. }
  4221. }
  4222. }
  4223. /* Generate code to implement SHARED from the sender (aka parent)
  4224. side. This is trickier, since GIMPLE_OMP_PARALLEL_CLAUSES doesn't
  4225. list things that got automatically shared. */
  4226. static void
  4227. lower_send_shared_vars (gimple_seq *ilist, gimple_seq *olist, omp_context *ctx)
  4228. {
  4229. tree var, ovar, nvar, f, x, record_type;
  4230. if (ctx->record_type == NULL)
  4231. return;
  4232. record_type = ctx->srecord_type ? ctx->srecord_type : ctx->record_type;
  4233. for (f = TYPE_FIELDS (record_type); f ; f = DECL_CHAIN (f))
  4234. {
  4235. ovar = DECL_ABSTRACT_ORIGIN (f);
  4236. nvar = maybe_lookup_decl (ovar, ctx);
  4237. if (!nvar || !DECL_HAS_VALUE_EXPR_P (nvar))
  4238. continue;
  4239. /* If CTX is a nested parallel directive. Find the immediately
  4240. enclosing parallel or workshare construct that contains a
  4241. mapping for OVAR. */
  4242. var = lookup_decl_in_outer_ctx (ovar, ctx);
  4243. if (use_pointer_for_field (ovar, ctx))
  4244. {
  4245. x = build_sender_ref (ovar, ctx);
  4246. var = build_fold_addr_expr (var);
  4247. gimplify_assign (x, var, ilist);
  4248. }
  4249. else
  4250. {
  4251. x = build_sender_ref (ovar, ctx);
  4252. gimplify_assign (x, var, ilist);
  4253. if (!TREE_READONLY (var)
  4254. /* We don't need to receive a new reference to a result
  4255. or parm decl. In fact we may not store to it as we will
  4256. invalidate any pending RSO and generate wrong gimple
  4257. during inlining. */
  4258. && !((TREE_CODE (var) == RESULT_DECL
  4259. || TREE_CODE (var) == PARM_DECL)
  4260. && DECL_BY_REFERENCE (var)))
  4261. {
  4262. x = build_sender_ref (ovar, ctx);
  4263. gimplify_assign (var, x, olist);
  4264. }
  4265. }
  4266. }
  4267. }
  4268. /* A convenience function to build an empty GIMPLE_COND with just the
  4269. condition. */
  4270. static gcond *
  4271. gimple_build_cond_empty (tree cond)
  4272. {
  4273. enum tree_code pred_code;
  4274. tree lhs, rhs;
  4275. gimple_cond_get_ops_from_tree (cond, &pred_code, &lhs, &rhs);
  4276. return gimple_build_cond (pred_code, lhs, rhs, NULL_TREE, NULL_TREE);
  4277. }
  4278. /* Build the function calls to GOMP_parallel_start etc to actually
  4279. generate the parallel operation. REGION is the parallel region
  4280. being expanded. BB is the block where to insert the code. WS_ARGS
  4281. will be set if this is a call to a combined parallel+workshare
  4282. construct, it contains the list of additional arguments needed by
  4283. the workshare construct. */
  4284. static void
  4285. expand_parallel_call (struct omp_region *region, basic_block bb,
  4286. gomp_parallel *entry_stmt,
  4287. vec<tree, va_gc> *ws_args)
  4288. {
  4289. tree t, t1, t2, val, cond, c, clauses, flags;
  4290. gimple_stmt_iterator gsi;
  4291. gimple stmt;
  4292. enum built_in_function start_ix;
  4293. int start_ix2;
  4294. location_t clause_loc;
  4295. vec<tree, va_gc> *args;
  4296. clauses = gimple_omp_parallel_clauses (entry_stmt);
  4297. /* Determine what flavor of GOMP_parallel we will be
  4298. emitting. */
  4299. start_ix = BUILT_IN_GOMP_PARALLEL;
  4300. if (is_combined_parallel (region))
  4301. {
  4302. switch (region->inner->type)
  4303. {
  4304. case GIMPLE_OMP_FOR:
  4305. gcc_assert (region->inner->sched_kind != OMP_CLAUSE_SCHEDULE_AUTO);
  4306. start_ix2 = ((int)BUILT_IN_GOMP_PARALLEL_LOOP_STATIC
  4307. + (region->inner->sched_kind
  4308. == OMP_CLAUSE_SCHEDULE_RUNTIME
  4309. ? 3 : region->inner->sched_kind));
  4310. start_ix = (enum built_in_function)start_ix2;
  4311. break;
  4312. case GIMPLE_OMP_SECTIONS:
  4313. start_ix = BUILT_IN_GOMP_PARALLEL_SECTIONS;
  4314. break;
  4315. default:
  4316. gcc_unreachable ();
  4317. }
  4318. }
  4319. /* By default, the value of NUM_THREADS is zero (selected at run time)
  4320. and there is no conditional. */
  4321. cond = NULL_TREE;
  4322. val = build_int_cst (unsigned_type_node, 0);
  4323. flags = build_int_cst (unsigned_type_node, 0);
  4324. c = find_omp_clause (clauses, OMP_CLAUSE_IF);
  4325. if (c)
  4326. cond = OMP_CLAUSE_IF_EXPR (c);
  4327. c = find_omp_clause (clauses, OMP_CLAUSE_NUM_THREADS);
  4328. if (c)
  4329. {
  4330. val = OMP_CLAUSE_NUM_THREADS_EXPR (c);
  4331. clause_loc = OMP_CLAUSE_LOCATION (c);
  4332. }
  4333. else
  4334. clause_loc = gimple_location (entry_stmt);
  4335. c = find_omp_clause (clauses, OMP_CLAUSE_PROC_BIND);
  4336. if (c)
  4337. flags = build_int_cst (unsigned_type_node, OMP_CLAUSE_PROC_BIND_KIND (c));
  4338. /* Ensure 'val' is of the correct type. */
  4339. val = fold_convert_loc (clause_loc, unsigned_type_node, val);
  4340. /* If we found the clause 'if (cond)', build either
  4341. (cond != 0) or (cond ? val : 1u). */
  4342. if (cond)
  4343. {
  4344. cond = gimple_boolify (cond);
  4345. if (integer_zerop (val))
  4346. val = fold_build2_loc (clause_loc,
  4347. EQ_EXPR, unsigned_type_node, cond,
  4348. build_int_cst (TREE_TYPE (cond), 0));
  4349. else
  4350. {
  4351. basic_block cond_bb, then_bb, else_bb;
  4352. edge e, e_then, e_else;
  4353. tree tmp_then, tmp_else, tmp_join, tmp_var;
  4354. tmp_var = create_tmp_var (TREE_TYPE (val));
  4355. if (gimple_in_ssa_p (cfun))
  4356. {
  4357. tmp_then = make_ssa_name (tmp_var);
  4358. tmp_else = make_ssa_name (tmp_var);
  4359. tmp_join = make_ssa_name (tmp_var);
  4360. }
  4361. else
  4362. {
  4363. tmp_then = tmp_var;
  4364. tmp_else = tmp_var;
  4365. tmp_join = tmp_var;
  4366. }
  4367. e = split_block (bb, NULL);
  4368. cond_bb = e->src;
  4369. bb = e->dest;
  4370. remove_edge (e);
  4371. then_bb = create_empty_bb (cond_bb);
  4372. else_bb = create_empty_bb (then_bb);
  4373. set_immediate_dominator (CDI_DOMINATORS, then_bb, cond_bb);
  4374. set_immediate_dominator (CDI_DOMINATORS, else_bb, cond_bb);
  4375. stmt = gimple_build_cond_empty (cond);
  4376. gsi = gsi_start_bb (cond_bb);
  4377. gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
  4378. gsi = gsi_start_bb (then_bb);
  4379. stmt = gimple_build_assign (tmp_then, val);
  4380. gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
  4381. gsi = gsi_start_bb (else_bb);
  4382. stmt = gimple_build_assign
  4383. (tmp_else, build_int_cst (unsigned_type_node, 1));
  4384. gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
  4385. make_edge (cond_bb, then_bb, EDGE_TRUE_VALUE);
  4386. make_edge (cond_bb, else_bb, EDGE_FALSE_VALUE);
  4387. add_bb_to_loop (then_bb, cond_bb->loop_father);
  4388. add_bb_to_loop (else_bb, cond_bb->loop_father);
  4389. e_then = make_edge (then_bb, bb, EDGE_FALLTHRU);
  4390. e_else = make_edge (else_bb, bb, EDGE_FALLTHRU);
  4391. if (gimple_in_ssa_p (cfun))
  4392. {
  4393. gphi *phi = create_phi_node (tmp_join, bb);
  4394. add_phi_arg (phi, tmp_then, e_then, UNKNOWN_LOCATION);
  4395. add_phi_arg (phi, tmp_else, e_else, UNKNOWN_LOCATION);
  4396. }
  4397. val = tmp_join;
  4398. }
  4399. gsi = gsi_start_bb (bb);
  4400. val = force_gimple_operand_gsi (&gsi, val, true, NULL_TREE,
  4401. false, GSI_CONTINUE_LINKING);
  4402. }
  4403. gsi = gsi_last_bb (bb);
  4404. t = gimple_omp_parallel_data_arg (entry_stmt);
  4405. if (t == NULL)
  4406. t1 = null_pointer_node;
  4407. else
  4408. t1 = build_fold_addr_expr (t);
  4409. t2 = build_fold_addr_expr (gimple_omp_parallel_child_fn (entry_stmt));
  4410. vec_alloc (args, 4 + vec_safe_length (ws_args));
  4411. args->quick_push (t2);
  4412. args->quick_push (t1);
  4413. args->quick_push (val);
  4414. if (ws_args)
  4415. args->splice (*ws_args);
  4416. args->quick_push (flags);
  4417. t = build_call_expr_loc_vec (UNKNOWN_LOCATION,
  4418. builtin_decl_explicit (start_ix), args);
  4419. force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
  4420. false, GSI_CONTINUE_LINKING);
  4421. }
  4422. /* Insert a function call whose name is FUNC_NAME with the information from
  4423. ENTRY_STMT into the basic_block BB. */
  4424. static void
  4425. expand_cilk_for_call (basic_block bb, gomp_parallel *entry_stmt,
  4426. vec <tree, va_gc> *ws_args)
  4427. {
  4428. tree t, t1, t2;
  4429. gimple_stmt_iterator gsi;
  4430. vec <tree, va_gc> *args;
  4431. gcc_assert (vec_safe_length (ws_args) == 2);
  4432. tree func_name = (*ws_args)[0];
  4433. tree grain = (*ws_args)[1];
  4434. tree clauses = gimple_omp_parallel_clauses (entry_stmt);
  4435. tree count = find_omp_clause (clauses, OMP_CLAUSE__CILK_FOR_COUNT_);
  4436. gcc_assert (count != NULL_TREE);
  4437. count = OMP_CLAUSE_OPERAND (count, 0);
  4438. gsi = gsi_last_bb (bb);
  4439. t = gimple_omp_parallel_data_arg (entry_stmt);
  4440. if (t == NULL)
  4441. t1 = null_pointer_node;
  4442. else
  4443. t1 = build_fold_addr_expr (t);
  4444. t2 = build_fold_addr_expr (gimple_omp_parallel_child_fn (entry_stmt));
  4445. vec_alloc (args, 4);
  4446. args->quick_push (t2);
  4447. args->quick_push (t1);
  4448. args->quick_push (count);
  4449. args->quick_push (grain);
  4450. t = build_call_expr_loc_vec (UNKNOWN_LOCATION, func_name, args);
  4451. force_gimple_operand_gsi (&gsi, t, true, NULL_TREE, false,
  4452. GSI_CONTINUE_LINKING);
  4453. }
  4454. /* Build the function call to GOMP_task to actually
  4455. generate the task operation. BB is the block where to insert the code. */
  4456. static void
  4457. expand_task_call (basic_block bb, gomp_task *entry_stmt)
  4458. {
  4459. tree t, t1, t2, t3, flags, cond, c, c2, clauses, depend;
  4460. gimple_stmt_iterator gsi;
  4461. location_t loc = gimple_location (entry_stmt);
  4462. clauses = gimple_omp_task_clauses (entry_stmt);
  4463. c = find_omp_clause (clauses, OMP_CLAUSE_IF);
  4464. if (c)
  4465. cond = gimple_boolify (OMP_CLAUSE_IF_EXPR (c));
  4466. else
  4467. cond = boolean_true_node;
  4468. c = find_omp_clause (clauses, OMP_CLAUSE_UNTIED);
  4469. c2 = find_omp_clause (clauses, OMP_CLAUSE_MERGEABLE);
  4470. depend = find_omp_clause (clauses, OMP_CLAUSE_DEPEND);
  4471. flags = build_int_cst (unsigned_type_node,
  4472. (c ? 1 : 0) + (c2 ? 4 : 0) + (depend ? 8 : 0));
  4473. c = find_omp_clause (clauses, OMP_CLAUSE_FINAL);
  4474. if (c)
  4475. {
  4476. c = gimple_boolify (OMP_CLAUSE_FINAL_EXPR (c));
  4477. c = fold_build3_loc (loc, COND_EXPR, unsigned_type_node, c,
  4478. build_int_cst (unsigned_type_node, 2),
  4479. build_int_cst (unsigned_type_node, 0));
  4480. flags = fold_build2_loc (loc, PLUS_EXPR, unsigned_type_node, flags, c);
  4481. }
  4482. if (depend)
  4483. depend = OMP_CLAUSE_DECL (depend);
  4484. else
  4485. depend = build_int_cst (ptr_type_node, 0);
  4486. gsi = gsi_last_bb (bb);
  4487. t = gimple_omp_task_data_arg (entry_stmt);
  4488. if (t == NULL)
  4489. t2 = null_pointer_node;
  4490. else
  4491. t2 = build_fold_addr_expr_loc (loc, t);
  4492. t1 = build_fold_addr_expr_loc (loc, gimple_omp_task_child_fn (entry_stmt));
  4493. t = gimple_omp_task_copy_fn (entry_stmt);
  4494. if (t == NULL)
  4495. t3 = null_pointer_node;
  4496. else
  4497. t3 = build_fold_addr_expr_loc (loc, t);
  4498. t = build_call_expr (builtin_decl_explicit (BUILT_IN_GOMP_TASK),
  4499. 8, t1, t2, t3,
  4500. gimple_omp_task_arg_size (entry_stmt),
  4501. gimple_omp_task_arg_align (entry_stmt), cond, flags,
  4502. depend);
  4503. force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
  4504. false, GSI_CONTINUE_LINKING);
  4505. }
  4506. /* If exceptions are enabled, wrap the statements in BODY in a MUST_NOT_THROW
  4507. catch handler and return it. This prevents programs from violating the
  4508. structured block semantics with throws. */
  4509. static gimple_seq
  4510. maybe_catch_exception (gimple_seq body)
  4511. {
  4512. gimple g;
  4513. tree decl;
  4514. if (!flag_exceptions)
  4515. return body;
  4516. if (lang_hooks.eh_protect_cleanup_actions != NULL)
  4517. decl = lang_hooks.eh_protect_cleanup_actions ();
  4518. else
  4519. decl = builtin_decl_explicit (BUILT_IN_TRAP);
  4520. g = gimple_build_eh_must_not_throw (decl);
  4521. g = gimple_build_try (body, gimple_seq_alloc_with_stmt (g),
  4522. GIMPLE_TRY_CATCH);
  4523. return gimple_seq_alloc_with_stmt (g);
  4524. }
  4525. /* Chain all the DECLs in LIST by their TREE_CHAIN fields. */
  4526. static tree
  4527. vec2chain (vec<tree, va_gc> *v)
  4528. {
  4529. tree chain = NULL_TREE, t;
  4530. unsigned ix;
  4531. FOR_EACH_VEC_SAFE_ELT_REVERSE (v, ix, t)
  4532. {
  4533. DECL_CHAIN (t) = chain;
  4534. chain = t;
  4535. }
  4536. return chain;
  4537. }
  4538. /* Remove barriers in REGION->EXIT's block. Note that this is only
  4539. valid for GIMPLE_OMP_PARALLEL regions. Since the end of a parallel region
  4540. is an implicit barrier, any workshare inside the GIMPLE_OMP_PARALLEL that
  4541. left a barrier at the end of the GIMPLE_OMP_PARALLEL region can now be
  4542. removed. */
  4543. static void
  4544. remove_exit_barrier (struct omp_region *region)
  4545. {
  4546. gimple_stmt_iterator gsi;
  4547. basic_block exit_bb;
  4548. edge_iterator ei;
  4549. edge e;
  4550. gimple stmt;
  4551. int any_addressable_vars = -1;
  4552. exit_bb = region->exit;
  4553. /* If the parallel region doesn't return, we don't have REGION->EXIT
  4554. block at all. */
  4555. if (! exit_bb)
  4556. return;
  4557. /* The last insn in the block will be the parallel's GIMPLE_OMP_RETURN. The
  4558. workshare's GIMPLE_OMP_RETURN will be in a preceding block. The kinds of
  4559. statements that can appear in between are extremely limited -- no
  4560. memory operations at all. Here, we allow nothing at all, so the
  4561. only thing we allow to precede this GIMPLE_OMP_RETURN is a label. */
  4562. gsi = gsi_last_bb (exit_bb);
  4563. gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_RETURN);
  4564. gsi_prev (&gsi);
  4565. if (!gsi_end_p (gsi) && gimple_code (gsi_stmt (gsi)) != GIMPLE_LABEL)
  4566. return;
  4567. FOR_EACH_EDGE (e, ei, exit_bb->preds)
  4568. {
  4569. gsi = gsi_last_bb (e->src);
  4570. if (gsi_end_p (gsi))
  4571. continue;
  4572. stmt = gsi_stmt (gsi);
  4573. if (gimple_code (stmt) == GIMPLE_OMP_RETURN
  4574. && !gimple_omp_return_nowait_p (stmt))
  4575. {
  4576. /* OpenMP 3.0 tasks unfortunately prevent this optimization
  4577. in many cases. If there could be tasks queued, the barrier
  4578. might be needed to let the tasks run before some local
  4579. variable of the parallel that the task uses as shared
  4580. runs out of scope. The task can be spawned either
  4581. from within current function (this would be easy to check)
  4582. or from some function it calls and gets passed an address
  4583. of such a variable. */
  4584. if (any_addressable_vars < 0)
  4585. {
  4586. gomp_parallel *parallel_stmt
  4587. = as_a <gomp_parallel *> (last_stmt (region->entry));
  4588. tree child_fun = gimple_omp_parallel_child_fn (parallel_stmt);
  4589. tree local_decls, block, decl;
  4590. unsigned ix;
  4591. any_addressable_vars = 0;
  4592. FOR_EACH_LOCAL_DECL (DECL_STRUCT_FUNCTION (child_fun), ix, decl)
  4593. if (TREE_ADDRESSABLE (decl))
  4594. {
  4595. any_addressable_vars = 1;
  4596. break;
  4597. }
  4598. for (block = gimple_block (stmt);
  4599. !any_addressable_vars
  4600. && block
  4601. && TREE_CODE (block) == BLOCK;
  4602. block = BLOCK_SUPERCONTEXT (block))
  4603. {
  4604. for (local_decls = BLOCK_VARS (block);
  4605. local_decls;
  4606. local_decls = DECL_CHAIN (local_decls))
  4607. if (TREE_ADDRESSABLE (local_decls))
  4608. {
  4609. any_addressable_vars = 1;
  4610. break;
  4611. }
  4612. if (block == gimple_block (parallel_stmt))
  4613. break;
  4614. }
  4615. }
  4616. if (!any_addressable_vars)
  4617. gimple_omp_return_set_nowait (stmt);
  4618. }
  4619. }
  4620. }
  4621. static void
  4622. remove_exit_barriers (struct omp_region *region)
  4623. {
  4624. if (region->type == GIMPLE_OMP_PARALLEL)
  4625. remove_exit_barrier (region);
  4626. if (region->inner)
  4627. {
  4628. region = region->inner;
  4629. remove_exit_barriers (region);
  4630. while (region->next)
  4631. {
  4632. region = region->next;
  4633. remove_exit_barriers (region);
  4634. }
  4635. }
  4636. }
  4637. /* Optimize omp_get_thread_num () and omp_get_num_threads ()
  4638. calls. These can't be declared as const functions, but
  4639. within one parallel body they are constant, so they can be
  4640. transformed there into __builtin_omp_get_{thread_num,num_threads} ()
  4641. which are declared const. Similarly for task body, except
  4642. that in untied task omp_get_thread_num () can change at any task
  4643. scheduling point. */
  4644. static void
  4645. optimize_omp_library_calls (gimple entry_stmt)
  4646. {
  4647. basic_block bb;
  4648. gimple_stmt_iterator gsi;
  4649. tree thr_num_tree = builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM);
  4650. tree thr_num_id = DECL_ASSEMBLER_NAME (thr_num_tree);
  4651. tree num_thr_tree = builtin_decl_explicit (BUILT_IN_OMP_GET_NUM_THREADS);
  4652. tree num_thr_id = DECL_ASSEMBLER_NAME (num_thr_tree);
  4653. bool untied_task = (gimple_code (entry_stmt) == GIMPLE_OMP_TASK
  4654. && find_omp_clause (gimple_omp_task_clauses (entry_stmt),
  4655. OMP_CLAUSE_UNTIED) != NULL);
  4656. FOR_EACH_BB_FN (bb, cfun)
  4657. for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
  4658. {
  4659. gimple call = gsi_stmt (gsi);
  4660. tree decl;
  4661. if (is_gimple_call (call)
  4662. && (decl = gimple_call_fndecl (call))
  4663. && DECL_EXTERNAL (decl)
  4664. && TREE_PUBLIC (decl)
  4665. && DECL_INITIAL (decl) == NULL)
  4666. {
  4667. tree built_in;
  4668. if (DECL_NAME (decl) == thr_num_id)
  4669. {
  4670. /* In #pragma omp task untied omp_get_thread_num () can change
  4671. during the execution of the task region. */
  4672. if (untied_task)
  4673. continue;
  4674. built_in = builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM);
  4675. }
  4676. else if (DECL_NAME (decl) == num_thr_id)
  4677. built_in = builtin_decl_explicit (BUILT_IN_OMP_GET_NUM_THREADS);
  4678. else
  4679. continue;
  4680. if (DECL_ASSEMBLER_NAME (decl) != DECL_ASSEMBLER_NAME (built_in)
  4681. || gimple_call_num_args (call) != 0)
  4682. continue;
  4683. if (flag_exceptions && !TREE_NOTHROW (decl))
  4684. continue;
  4685. if (TREE_CODE (TREE_TYPE (decl)) != FUNCTION_TYPE
  4686. || !types_compatible_p (TREE_TYPE (TREE_TYPE (decl)),
  4687. TREE_TYPE (TREE_TYPE (built_in))))
  4688. continue;
  4689. gimple_call_set_fndecl (call, built_in);
  4690. }
  4691. }
  4692. }
  4693. /* Callback for expand_omp_build_assign. Return non-NULL if *tp needs to be
  4694. regimplified. */
  4695. static tree
  4696. expand_omp_regimplify_p (tree *tp, int *walk_subtrees, void *)
  4697. {
  4698. tree t = *tp;
  4699. /* Any variable with DECL_VALUE_EXPR needs to be regimplified. */
  4700. if (TREE_CODE (t) == VAR_DECL && DECL_HAS_VALUE_EXPR_P (t))
  4701. return t;
  4702. if (TREE_CODE (t) == ADDR_EXPR)
  4703. recompute_tree_invariant_for_addr_expr (t);
  4704. *walk_subtrees = !TYPE_P (t) && !DECL_P (t);
  4705. return NULL_TREE;
  4706. }
  4707. /* Prepend TO = FROM assignment before *GSI_P. */
  4708. static void
  4709. expand_omp_build_assign (gimple_stmt_iterator *gsi_p, tree to, tree from)
  4710. {
  4711. bool simple_p = DECL_P (to) && TREE_ADDRESSABLE (to);
  4712. from = force_gimple_operand_gsi (gsi_p, from, simple_p, NULL_TREE,
  4713. true, GSI_SAME_STMT);
  4714. gimple stmt = gimple_build_assign (to, from);
  4715. gsi_insert_before (gsi_p, stmt, GSI_SAME_STMT);
  4716. if (walk_tree (&from, expand_omp_regimplify_p, NULL, NULL)
  4717. || walk_tree (&to, expand_omp_regimplify_p, NULL, NULL))
  4718. {
  4719. gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
  4720. gimple_regimplify_operands (stmt, &gsi);
  4721. }
  4722. }
  4723. /* Expand the OpenMP parallel or task directive starting at REGION. */
  4724. static void
  4725. expand_omp_taskreg (struct omp_region *region)
  4726. {
  4727. basic_block entry_bb, exit_bb, new_bb;
  4728. struct function *child_cfun;
  4729. tree child_fn, block, t;
  4730. gimple_stmt_iterator gsi;
  4731. gimple entry_stmt, stmt;
  4732. edge e;
  4733. vec<tree, va_gc> *ws_args;
  4734. entry_stmt = last_stmt (region->entry);
  4735. child_fn = gimple_omp_taskreg_child_fn (entry_stmt);
  4736. child_cfun = DECL_STRUCT_FUNCTION (child_fn);
  4737. entry_bb = region->entry;
  4738. if (gimple_code (entry_stmt) == GIMPLE_OMP_TASK)
  4739. exit_bb = region->cont;
  4740. else
  4741. exit_bb = region->exit;
  4742. bool is_cilk_for
  4743. = (flag_cilkplus
  4744. && gimple_code (entry_stmt) == GIMPLE_OMP_PARALLEL
  4745. && find_omp_clause (gimple_omp_parallel_clauses (entry_stmt),
  4746. OMP_CLAUSE__CILK_FOR_COUNT_) != NULL_TREE);
  4747. if (is_cilk_for)
  4748. /* If it is a _Cilk_for statement, it is modelled *like* a parallel for,
  4749. and the inner statement contains the name of the built-in function
  4750. and grain. */
  4751. ws_args = region->inner->ws_args;
  4752. else if (is_combined_parallel (region))
  4753. ws_args = region->ws_args;
  4754. else
  4755. ws_args = NULL;
  4756. if (child_cfun->cfg)
  4757. {
  4758. /* Due to inlining, it may happen that we have already outlined
  4759. the region, in which case all we need to do is make the
  4760. sub-graph unreachable and emit the parallel call. */
  4761. edge entry_succ_e, exit_succ_e;
  4762. entry_succ_e = single_succ_edge (entry_bb);
  4763. gsi = gsi_last_bb (entry_bb);
  4764. gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_PARALLEL
  4765. || gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_TASK);
  4766. gsi_remove (&gsi, true);
  4767. new_bb = entry_bb;
  4768. if (exit_bb)
  4769. {
  4770. exit_succ_e = single_succ_edge (exit_bb);
  4771. make_edge (new_bb, exit_succ_e->dest, EDGE_FALLTHRU);
  4772. }
  4773. remove_edge_and_dominated_blocks (entry_succ_e);
  4774. }
  4775. else
  4776. {
  4777. unsigned srcidx, dstidx, num;
  4778. /* If the parallel region needs data sent from the parent
  4779. function, then the very first statement (except possible
  4780. tree profile counter updates) of the parallel body
  4781. is a copy assignment .OMP_DATA_I = &.OMP_DATA_O. Since
  4782. &.OMP_DATA_O is passed as an argument to the child function,
  4783. we need to replace it with the argument as seen by the child
  4784. function.
  4785. In most cases, this will end up being the identity assignment
  4786. .OMP_DATA_I = .OMP_DATA_I. However, if the parallel body had
  4787. a function call that has been inlined, the original PARM_DECL
  4788. .OMP_DATA_I may have been converted into a different local
  4789. variable. In which case, we need to keep the assignment. */
  4790. if (gimple_omp_taskreg_data_arg (entry_stmt))
  4791. {
  4792. basic_block entry_succ_bb
  4793. = single_succ_p (entry_bb) ? single_succ (entry_bb)
  4794. : FALLTHRU_EDGE (entry_bb)->dest;
  4795. tree arg, narg;
  4796. gimple parcopy_stmt = NULL;
  4797. for (gsi = gsi_start_bb (entry_succ_bb); ; gsi_next (&gsi))
  4798. {
  4799. gimple stmt;
  4800. gcc_assert (!gsi_end_p (gsi));
  4801. stmt = gsi_stmt (gsi);
  4802. if (gimple_code (stmt) != GIMPLE_ASSIGN)
  4803. continue;
  4804. if (gimple_num_ops (stmt) == 2)
  4805. {
  4806. tree arg = gimple_assign_rhs1 (stmt);
  4807. /* We're ignore the subcode because we're
  4808. effectively doing a STRIP_NOPS. */
  4809. if (TREE_CODE (arg) == ADDR_EXPR
  4810. && TREE_OPERAND (arg, 0)
  4811. == gimple_omp_taskreg_data_arg (entry_stmt))
  4812. {
  4813. parcopy_stmt = stmt;
  4814. break;
  4815. }
  4816. }
  4817. }
  4818. gcc_assert (parcopy_stmt != NULL);
  4819. arg = DECL_ARGUMENTS (child_fn);
  4820. if (!gimple_in_ssa_p (cfun))
  4821. {
  4822. if (gimple_assign_lhs (parcopy_stmt) == arg)
  4823. gsi_remove (&gsi, true);
  4824. else
  4825. {
  4826. /* ?? Is setting the subcode really necessary ?? */
  4827. gimple_omp_set_subcode (parcopy_stmt, TREE_CODE (arg));
  4828. gimple_assign_set_rhs1 (parcopy_stmt, arg);
  4829. }
  4830. }
  4831. else
  4832. {
  4833. /* If we are in ssa form, we must load the value from the default
  4834. definition of the argument. That should not be defined now,
  4835. since the argument is not used uninitialized. */
  4836. gcc_assert (ssa_default_def (cfun, arg) == NULL);
  4837. narg = make_ssa_name (arg, gimple_build_nop ());
  4838. set_ssa_default_def (cfun, arg, narg);
  4839. /* ?? Is setting the subcode really necessary ?? */
  4840. gimple_omp_set_subcode (parcopy_stmt, TREE_CODE (narg));
  4841. gimple_assign_set_rhs1 (parcopy_stmt, narg);
  4842. update_stmt (parcopy_stmt);
  4843. }
  4844. }
  4845. /* Declare local variables needed in CHILD_CFUN. */
  4846. block = DECL_INITIAL (child_fn);
  4847. BLOCK_VARS (block) = vec2chain (child_cfun->local_decls);
  4848. /* The gimplifier could record temporaries in parallel/task block
  4849. rather than in containing function's local_decls chain,
  4850. which would mean cgraph missed finalizing them. Do it now. */
  4851. for (t = BLOCK_VARS (block); t; t = DECL_CHAIN (t))
  4852. if (TREE_CODE (t) == VAR_DECL
  4853. && TREE_STATIC (t)
  4854. && !DECL_EXTERNAL (t))
  4855. varpool_node::finalize_decl (t);
  4856. DECL_SAVED_TREE (child_fn) = NULL;
  4857. /* We'll create a CFG for child_fn, so no gimple body is needed. */
  4858. gimple_set_body (child_fn, NULL);
  4859. TREE_USED (block) = 1;
  4860. /* Reset DECL_CONTEXT on function arguments. */
  4861. for (t = DECL_ARGUMENTS (child_fn); t; t = DECL_CHAIN (t))
  4862. DECL_CONTEXT (t) = child_fn;
  4863. /* Split ENTRY_BB at GIMPLE_OMP_PARALLEL or GIMPLE_OMP_TASK,
  4864. so that it can be moved to the child function. */
  4865. gsi = gsi_last_bb (entry_bb);
  4866. stmt = gsi_stmt (gsi);
  4867. gcc_assert (stmt && (gimple_code (stmt) == GIMPLE_OMP_PARALLEL
  4868. || gimple_code (stmt) == GIMPLE_OMP_TASK));
  4869. e = split_block (entry_bb, stmt);
  4870. gsi_remove (&gsi, true);
  4871. entry_bb = e->dest;
  4872. edge e2 = NULL;
  4873. if (gimple_code (entry_stmt) == GIMPLE_OMP_PARALLEL)
  4874. single_succ_edge (entry_bb)->flags = EDGE_FALLTHRU;
  4875. else
  4876. {
  4877. e2 = make_edge (e->src, BRANCH_EDGE (entry_bb)->dest, EDGE_ABNORMAL);
  4878. gcc_assert (e2->dest == region->exit);
  4879. remove_edge (BRANCH_EDGE (entry_bb));
  4880. set_immediate_dominator (CDI_DOMINATORS, e2->dest, e->src);
  4881. gsi = gsi_last_bb (region->exit);
  4882. gcc_assert (!gsi_end_p (gsi)
  4883. && gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_RETURN);
  4884. gsi_remove (&gsi, true);
  4885. }
  4886. /* Convert GIMPLE_OMP_{RETURN,CONTINUE} into a RETURN_EXPR. */
  4887. if (exit_bb)
  4888. {
  4889. gsi = gsi_last_bb (exit_bb);
  4890. gcc_assert (!gsi_end_p (gsi)
  4891. && (gimple_code (gsi_stmt (gsi))
  4892. == (e2 ? GIMPLE_OMP_CONTINUE : GIMPLE_OMP_RETURN)));
  4893. stmt = gimple_build_return (NULL);
  4894. gsi_insert_after (&gsi, stmt, GSI_SAME_STMT);
  4895. gsi_remove (&gsi, true);
  4896. }
  4897. /* Move the parallel region into CHILD_CFUN. */
  4898. if (gimple_in_ssa_p (cfun))
  4899. {
  4900. init_tree_ssa (child_cfun);
  4901. init_ssa_operands (child_cfun);
  4902. child_cfun->gimple_df->in_ssa_p = true;
  4903. block = NULL_TREE;
  4904. }
  4905. else
  4906. block = gimple_block (entry_stmt);
  4907. new_bb = move_sese_region_to_fn (child_cfun, entry_bb, exit_bb, block);
  4908. if (exit_bb)
  4909. single_succ_edge (new_bb)->flags = EDGE_FALLTHRU;
  4910. if (e2)
  4911. {
  4912. basic_block dest_bb = e2->dest;
  4913. if (!exit_bb)
  4914. make_edge (new_bb, dest_bb, EDGE_FALLTHRU);
  4915. remove_edge (e2);
  4916. set_immediate_dominator (CDI_DOMINATORS, dest_bb, new_bb);
  4917. }
  4918. /* When the OMP expansion process cannot guarantee an up-to-date
  4919. loop tree arrange for the child function to fixup loops. */
  4920. if (loops_state_satisfies_p (LOOPS_NEED_FIXUP))
  4921. child_cfun->x_current_loops->state |= LOOPS_NEED_FIXUP;
  4922. /* Remove non-local VAR_DECLs from child_cfun->local_decls list. */
  4923. num = vec_safe_length (child_cfun->local_decls);
  4924. for (srcidx = 0, dstidx = 0; srcidx < num; srcidx++)
  4925. {
  4926. t = (*child_cfun->local_decls)[srcidx];
  4927. if (DECL_CONTEXT (t) == cfun->decl)
  4928. continue;
  4929. if (srcidx != dstidx)
  4930. (*child_cfun->local_decls)[dstidx] = t;
  4931. dstidx++;
  4932. }
  4933. if (dstidx != num)
  4934. vec_safe_truncate (child_cfun->local_decls, dstidx);
  4935. /* Inform the callgraph about the new function. */
  4936. child_cfun->curr_properties = cfun->curr_properties;
  4937. child_cfun->has_simduid_loops |= cfun->has_simduid_loops;
  4938. child_cfun->has_force_vectorize_loops |= cfun->has_force_vectorize_loops;
  4939. cgraph_node::add_new_function (child_fn, true);
  4940. cgraph_node::get (child_fn)->parallelized_function = 1;
  4941. /* Fix the callgraph edges for child_cfun. Those for cfun will be
  4942. fixed in a following pass. */
  4943. push_cfun (child_cfun);
  4944. if (optimize)
  4945. optimize_omp_library_calls (entry_stmt);
  4946. cgraph_edge::rebuild_edges ();
  4947. /* Some EH regions might become dead, see PR34608. If
  4948. pass_cleanup_cfg isn't the first pass to happen with the
  4949. new child, these dead EH edges might cause problems.
  4950. Clean them up now. */
  4951. if (flag_exceptions)
  4952. {
  4953. basic_block bb;
  4954. bool changed = false;
  4955. FOR_EACH_BB_FN (bb, cfun)
  4956. changed |= gimple_purge_dead_eh_edges (bb);
  4957. if (changed)
  4958. cleanup_tree_cfg ();
  4959. }
  4960. if (gimple_in_ssa_p (cfun))
  4961. update_ssa (TODO_update_ssa);
  4962. pop_cfun ();
  4963. }
  4964. /* Emit a library call to launch the children threads. */
  4965. if (is_cilk_for)
  4966. expand_cilk_for_call (new_bb,
  4967. as_a <gomp_parallel *> (entry_stmt), ws_args);
  4968. else if (gimple_code (entry_stmt) == GIMPLE_OMP_PARALLEL)
  4969. expand_parallel_call (region, new_bb,
  4970. as_a <gomp_parallel *> (entry_stmt), ws_args);
  4971. else
  4972. expand_task_call (new_bb, as_a <gomp_task *> (entry_stmt));
  4973. if (gimple_in_ssa_p (cfun))
  4974. update_ssa (TODO_update_ssa_only_virtuals);
  4975. }
  4976. /* Helper function for expand_omp_{for_*,simd}. If this is the outermost
  4977. of the combined collapse > 1 loop constructs, generate code like:
  4978. if (__builtin_expect (N32 cond3 N31, 0)) goto ZERO_ITER_BB;
  4979. if (cond3 is <)
  4980. adj = STEP3 - 1;
  4981. else
  4982. adj = STEP3 + 1;
  4983. count3 = (adj + N32 - N31) / STEP3;
  4984. if (__builtin_expect (N22 cond2 N21, 0)) goto ZERO_ITER_BB;
  4985. if (cond2 is <)
  4986. adj = STEP2 - 1;
  4987. else
  4988. adj = STEP2 + 1;
  4989. count2 = (adj + N22 - N21) / STEP2;
  4990. if (__builtin_expect (N12 cond1 N11, 0)) goto ZERO_ITER_BB;
  4991. if (cond1 is <)
  4992. adj = STEP1 - 1;
  4993. else
  4994. adj = STEP1 + 1;
  4995. count1 = (adj + N12 - N11) / STEP1;
  4996. count = count1 * count2 * count3;
  4997. Furthermore, if ZERO_ITER_BB is NULL, create a BB which does:
  4998. count = 0;
  4999. and set ZERO_ITER_BB to that bb. If this isn't the outermost
  5000. of the combined loop constructs, just initialize COUNTS array
  5001. from the _looptemp_ clauses. */
  5002. /* NOTE: It *could* be better to moosh all of the BBs together,
  5003. creating one larger BB with all the computation and the unexpected
  5004. jump at the end. I.e.
  5005. bool zero3, zero2, zero1, zero;
  5006. zero3 = N32 c3 N31;
  5007. count3 = (N32 - N31) /[cl] STEP3;
  5008. zero2 = N22 c2 N21;
  5009. count2 = (N22 - N21) /[cl] STEP2;
  5010. zero1 = N12 c1 N11;
  5011. count1 = (N12 - N11) /[cl] STEP1;
  5012. zero = zero3 || zero2 || zero1;
  5013. count = count1 * count2 * count3;
  5014. if (__builtin_expect(zero, false)) goto zero_iter_bb;
  5015. After all, we expect the zero=false, and thus we expect to have to
  5016. evaluate all of the comparison expressions, so short-circuiting
  5017. oughtn't be a win. Since the condition isn't protecting a
  5018. denominator, we're not concerned about divide-by-zero, so we can
  5019. fully evaluate count even if a numerator turned out to be wrong.
  5020. It seems like putting this all together would create much better
  5021. scheduling opportunities, and less pressure on the chip's branch
  5022. predictor. */
  5023. static void
  5024. expand_omp_for_init_counts (struct omp_for_data *fd, gimple_stmt_iterator *gsi,
  5025. basic_block &entry_bb, tree *counts,
  5026. basic_block &zero_iter_bb, int &first_zero_iter,
  5027. basic_block &l2_dom_bb)
  5028. {
  5029. tree t, type = TREE_TYPE (fd->loop.v);
  5030. edge e, ne;
  5031. int i;
  5032. /* Collapsed loops need work for expansion into SSA form. */
  5033. gcc_assert (!gimple_in_ssa_p (cfun));
  5034. if (gimple_omp_for_combined_into_p (fd->for_stmt)
  5035. && TREE_CODE (fd->loop.n2) != INTEGER_CST)
  5036. {
  5037. /* First two _looptemp_ clauses are for istart/iend, counts[0]
  5038. isn't supposed to be handled, as the inner loop doesn't
  5039. use it. */
  5040. tree innerc = find_omp_clause (gimple_omp_for_clauses (fd->for_stmt),
  5041. OMP_CLAUSE__LOOPTEMP_);
  5042. gcc_assert (innerc);
  5043. for (i = 0; i < fd->collapse; i++)
  5044. {
  5045. innerc = find_omp_clause (OMP_CLAUSE_CHAIN (innerc),
  5046. OMP_CLAUSE__LOOPTEMP_);
  5047. gcc_assert (innerc);
  5048. if (i)
  5049. counts[i] = OMP_CLAUSE_DECL (innerc);
  5050. else
  5051. counts[0] = NULL_TREE;
  5052. }
  5053. return;
  5054. }
  5055. for (i = 0; i < fd->collapse; i++)
  5056. {
  5057. tree itype = TREE_TYPE (fd->loops[i].v);
  5058. if (SSA_VAR_P (fd->loop.n2)
  5059. && ((t = fold_binary (fd->loops[i].cond_code, boolean_type_node,
  5060. fold_convert (itype, fd->loops[i].n1),
  5061. fold_convert (itype, fd->loops[i].n2)))
  5062. == NULL_TREE || !integer_onep (t)))
  5063. {
  5064. gcond *cond_stmt;
  5065. tree n1, n2;
  5066. n1 = fold_convert (itype, unshare_expr (fd->loops[i].n1));
  5067. n1 = force_gimple_operand_gsi (gsi, n1, true, NULL_TREE,
  5068. true, GSI_SAME_STMT);
  5069. n2 = fold_convert (itype, unshare_expr (fd->loops[i].n2));
  5070. n2 = force_gimple_operand_gsi (gsi, n2, true, NULL_TREE,
  5071. true, GSI_SAME_STMT);
  5072. cond_stmt = gimple_build_cond (fd->loops[i].cond_code, n1, n2,
  5073. NULL_TREE, NULL_TREE);
  5074. gsi_insert_before (gsi, cond_stmt, GSI_SAME_STMT);
  5075. if (walk_tree (gimple_cond_lhs_ptr (cond_stmt),
  5076. expand_omp_regimplify_p, NULL, NULL)
  5077. || walk_tree (gimple_cond_rhs_ptr (cond_stmt),
  5078. expand_omp_regimplify_p, NULL, NULL))
  5079. {
  5080. *gsi = gsi_for_stmt (cond_stmt);
  5081. gimple_regimplify_operands (cond_stmt, gsi);
  5082. }
  5083. e = split_block (entry_bb, cond_stmt);
  5084. if (zero_iter_bb == NULL)
  5085. {
  5086. gassign *assign_stmt;
  5087. first_zero_iter = i;
  5088. zero_iter_bb = create_empty_bb (entry_bb);
  5089. add_bb_to_loop (zero_iter_bb, entry_bb->loop_father);
  5090. *gsi = gsi_after_labels (zero_iter_bb);
  5091. assign_stmt = gimple_build_assign (fd->loop.n2,
  5092. build_zero_cst (type));
  5093. gsi_insert_before (gsi, assign_stmt, GSI_SAME_STMT);
  5094. set_immediate_dominator (CDI_DOMINATORS, zero_iter_bb,
  5095. entry_bb);
  5096. }
  5097. ne = make_edge (entry_bb, zero_iter_bb, EDGE_FALSE_VALUE);
  5098. ne->probability = REG_BR_PROB_BASE / 2000 - 1;
  5099. e->flags = EDGE_TRUE_VALUE;
  5100. e->probability = REG_BR_PROB_BASE - ne->probability;
  5101. if (l2_dom_bb == NULL)
  5102. l2_dom_bb = entry_bb;
  5103. entry_bb = e->dest;
  5104. *gsi = gsi_last_bb (entry_bb);
  5105. }
  5106. if (POINTER_TYPE_P (itype))
  5107. itype = signed_type_for (itype);
  5108. t = build_int_cst (itype, (fd->loops[i].cond_code == LT_EXPR
  5109. ? -1 : 1));
  5110. t = fold_build2 (PLUS_EXPR, itype,
  5111. fold_convert (itype, fd->loops[i].step), t);
  5112. t = fold_build2 (PLUS_EXPR, itype, t,
  5113. fold_convert (itype, fd->loops[i].n2));
  5114. t = fold_build2 (MINUS_EXPR, itype, t,
  5115. fold_convert (itype, fd->loops[i].n1));
  5116. /* ?? We could probably use CEIL_DIV_EXPR instead of
  5117. TRUNC_DIV_EXPR and adjusting by hand. Unless we can't
  5118. generate the same code in the end because generically we
  5119. don't know that the values involved must be negative for
  5120. GT?? */
  5121. if (TYPE_UNSIGNED (itype) && fd->loops[i].cond_code == GT_EXPR)
  5122. t = fold_build2 (TRUNC_DIV_EXPR, itype,
  5123. fold_build1 (NEGATE_EXPR, itype, t),
  5124. fold_build1 (NEGATE_EXPR, itype,
  5125. fold_convert (itype,
  5126. fd->loops[i].step)));
  5127. else
  5128. t = fold_build2 (TRUNC_DIV_EXPR, itype, t,
  5129. fold_convert (itype, fd->loops[i].step));
  5130. t = fold_convert (type, t);
  5131. if (TREE_CODE (t) == INTEGER_CST)
  5132. counts[i] = t;
  5133. else
  5134. {
  5135. counts[i] = create_tmp_reg (type, ".count");
  5136. expand_omp_build_assign (gsi, counts[i], t);
  5137. }
  5138. if (SSA_VAR_P (fd->loop.n2))
  5139. {
  5140. if (i == 0)
  5141. t = counts[0];
  5142. else
  5143. t = fold_build2 (MULT_EXPR, type, fd->loop.n2, counts[i]);
  5144. expand_omp_build_assign (gsi, fd->loop.n2, t);
  5145. }
  5146. }
  5147. }
  5148. /* Helper function for expand_omp_{for_*,simd}. Generate code like:
  5149. T = V;
  5150. V3 = N31 + (T % count3) * STEP3;
  5151. T = T / count3;
  5152. V2 = N21 + (T % count2) * STEP2;
  5153. T = T / count2;
  5154. V1 = N11 + T * STEP1;
  5155. if this loop doesn't have an inner loop construct combined with it.
  5156. If it does have an inner loop construct combined with it and the
  5157. iteration count isn't known constant, store values from counts array
  5158. into its _looptemp_ temporaries instead. */
  5159. static void
  5160. expand_omp_for_init_vars (struct omp_for_data *fd, gimple_stmt_iterator *gsi,
  5161. tree *counts, gimple inner_stmt, tree startvar)
  5162. {
  5163. int i;
  5164. if (gimple_omp_for_combined_p (fd->for_stmt))
  5165. {
  5166. /* If fd->loop.n2 is constant, then no propagation of the counts
  5167. is needed, they are constant. */
  5168. if (TREE_CODE (fd->loop.n2) == INTEGER_CST)
  5169. return;
  5170. tree clauses = gimple_code (inner_stmt) == GIMPLE_OMP_PARALLEL
  5171. ? gimple_omp_parallel_clauses (inner_stmt)
  5172. : gimple_omp_for_clauses (inner_stmt);
  5173. /* First two _looptemp_ clauses are for istart/iend, counts[0]
  5174. isn't supposed to be handled, as the inner loop doesn't
  5175. use it. */
  5176. tree innerc = find_omp_clause (clauses, OMP_CLAUSE__LOOPTEMP_);
  5177. gcc_assert (innerc);
  5178. for (i = 0; i < fd->collapse; i++)
  5179. {
  5180. innerc = find_omp_clause (OMP_CLAUSE_CHAIN (innerc),
  5181. OMP_CLAUSE__LOOPTEMP_);
  5182. gcc_assert (innerc);
  5183. if (i)
  5184. {
  5185. tree tem = OMP_CLAUSE_DECL (innerc);
  5186. tree t = fold_convert (TREE_TYPE (tem), counts[i]);
  5187. t = force_gimple_operand_gsi (gsi, t, false, NULL_TREE,
  5188. false, GSI_CONTINUE_LINKING);
  5189. gassign *stmt = gimple_build_assign (tem, t);
  5190. gsi_insert_after (gsi, stmt, GSI_CONTINUE_LINKING);
  5191. }
  5192. }
  5193. return;
  5194. }
  5195. tree type = TREE_TYPE (fd->loop.v);
  5196. tree tem = create_tmp_reg (type, ".tem");
  5197. gassign *stmt = gimple_build_assign (tem, startvar);
  5198. gsi_insert_after (gsi, stmt, GSI_CONTINUE_LINKING);
  5199. for (i = fd->collapse - 1; i >= 0; i--)
  5200. {
  5201. tree vtype = TREE_TYPE (fd->loops[i].v), itype, t;
  5202. itype = vtype;
  5203. if (POINTER_TYPE_P (vtype))
  5204. itype = signed_type_for (vtype);
  5205. if (i != 0)
  5206. t = fold_build2 (TRUNC_MOD_EXPR, type, tem, counts[i]);
  5207. else
  5208. t = tem;
  5209. t = fold_convert (itype, t);
  5210. t = fold_build2 (MULT_EXPR, itype, t,
  5211. fold_convert (itype, fd->loops[i].step));
  5212. if (POINTER_TYPE_P (vtype))
  5213. t = fold_build_pointer_plus (fd->loops[i].n1, t);
  5214. else
  5215. t = fold_build2 (PLUS_EXPR, itype, fd->loops[i].n1, t);
  5216. t = force_gimple_operand_gsi (gsi, t,
  5217. DECL_P (fd->loops[i].v)
  5218. && TREE_ADDRESSABLE (fd->loops[i].v),
  5219. NULL_TREE, false,
  5220. GSI_CONTINUE_LINKING);
  5221. stmt = gimple_build_assign (fd->loops[i].v, t);
  5222. gsi_insert_after (gsi, stmt, GSI_CONTINUE_LINKING);
  5223. if (i != 0)
  5224. {
  5225. t = fold_build2 (TRUNC_DIV_EXPR, type, tem, counts[i]);
  5226. t = force_gimple_operand_gsi (gsi, t, false, NULL_TREE,
  5227. false, GSI_CONTINUE_LINKING);
  5228. stmt = gimple_build_assign (tem, t);
  5229. gsi_insert_after (gsi, stmt, GSI_CONTINUE_LINKING);
  5230. }
  5231. }
  5232. }
  5233. /* Helper function for expand_omp_for_*. Generate code like:
  5234. L10:
  5235. V3 += STEP3;
  5236. if (V3 cond3 N32) goto BODY_BB; else goto L11;
  5237. L11:
  5238. V3 = N31;
  5239. V2 += STEP2;
  5240. if (V2 cond2 N22) goto BODY_BB; else goto L12;
  5241. L12:
  5242. V2 = N21;
  5243. V1 += STEP1;
  5244. goto BODY_BB; */
  5245. static basic_block
  5246. extract_omp_for_update_vars (struct omp_for_data *fd, basic_block cont_bb,
  5247. basic_block body_bb)
  5248. {
  5249. basic_block last_bb, bb, collapse_bb = NULL;
  5250. int i;
  5251. gimple_stmt_iterator gsi;
  5252. edge e;
  5253. tree t;
  5254. gimple stmt;
  5255. last_bb = cont_bb;
  5256. for (i = fd->collapse - 1; i >= 0; i--)
  5257. {
  5258. tree vtype = TREE_TYPE (fd->loops[i].v);
  5259. bb = create_empty_bb (last_bb);
  5260. add_bb_to_loop (bb, last_bb->loop_father);
  5261. gsi = gsi_start_bb (bb);
  5262. if (i < fd->collapse - 1)
  5263. {
  5264. e = make_edge (last_bb, bb, EDGE_FALSE_VALUE);
  5265. e->probability = REG_BR_PROB_BASE / 8;
  5266. t = fd->loops[i + 1].n1;
  5267. t = force_gimple_operand_gsi (&gsi, t,
  5268. DECL_P (fd->loops[i + 1].v)
  5269. && TREE_ADDRESSABLE (fd->loops[i
  5270. + 1].v),
  5271. NULL_TREE, false,
  5272. GSI_CONTINUE_LINKING);
  5273. stmt = gimple_build_assign (fd->loops[i + 1].v, t);
  5274. gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
  5275. }
  5276. else
  5277. collapse_bb = bb;
  5278. set_immediate_dominator (CDI_DOMINATORS, bb, last_bb);
  5279. if (POINTER_TYPE_P (vtype))
  5280. t = fold_build_pointer_plus (fd->loops[i].v, fd->loops[i].step);
  5281. else
  5282. t = fold_build2 (PLUS_EXPR, vtype, fd->loops[i].v, fd->loops[i].step);
  5283. t = force_gimple_operand_gsi (&gsi, t,
  5284. DECL_P (fd->loops[i].v)
  5285. && TREE_ADDRESSABLE (fd->loops[i].v),
  5286. NULL_TREE, false, GSI_CONTINUE_LINKING);
  5287. stmt = gimple_build_assign (fd->loops[i].v, t);
  5288. gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
  5289. if (i > 0)
  5290. {
  5291. t = fd->loops[i].n2;
  5292. t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
  5293. false, GSI_CONTINUE_LINKING);
  5294. tree v = fd->loops[i].v;
  5295. if (DECL_P (v) && TREE_ADDRESSABLE (v))
  5296. v = force_gimple_operand_gsi (&gsi, v, true, NULL_TREE,
  5297. false, GSI_CONTINUE_LINKING);
  5298. t = fold_build2 (fd->loops[i].cond_code, boolean_type_node, v, t);
  5299. stmt = gimple_build_cond_empty (t);
  5300. gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
  5301. e = make_edge (bb, body_bb, EDGE_TRUE_VALUE);
  5302. e->probability = REG_BR_PROB_BASE * 7 / 8;
  5303. }
  5304. else
  5305. make_edge (bb, body_bb, EDGE_FALLTHRU);
  5306. last_bb = bb;
  5307. }
  5308. return collapse_bb;
  5309. }
  5310. /* A subroutine of expand_omp_for. Generate code for a parallel
  5311. loop with any schedule. Given parameters:
  5312. for (V = N1; V cond N2; V += STEP) BODY;
  5313. where COND is "<" or ">", we generate pseudocode
  5314. more = GOMP_loop_foo_start (N1, N2, STEP, CHUNK, &istart0, &iend0);
  5315. if (more) goto L0; else goto L3;
  5316. L0:
  5317. V = istart0;
  5318. iend = iend0;
  5319. L1:
  5320. BODY;
  5321. V += STEP;
  5322. if (V cond iend) goto L1; else goto L2;
  5323. L2:
  5324. if (GOMP_loop_foo_next (&istart0, &iend0)) goto L0; else goto L3;
  5325. L3:
  5326. If this is a combined omp parallel loop, instead of the call to
  5327. GOMP_loop_foo_start, we call GOMP_loop_foo_next.
  5328. If this is gimple_omp_for_combined_p loop, then instead of assigning
  5329. V and iend in L0 we assign the first two _looptemp_ clause decls of the
  5330. inner GIMPLE_OMP_FOR and V += STEP; and
  5331. if (V cond iend) goto L1; else goto L2; are removed.
  5332. For collapsed loops, given parameters:
  5333. collapse(3)
  5334. for (V1 = N11; V1 cond1 N12; V1 += STEP1)
  5335. for (V2 = N21; V2 cond2 N22; V2 += STEP2)
  5336. for (V3 = N31; V3 cond3 N32; V3 += STEP3)
  5337. BODY;
  5338. we generate pseudocode
  5339. if (__builtin_expect (N32 cond3 N31, 0)) goto Z0;
  5340. if (cond3 is <)
  5341. adj = STEP3 - 1;
  5342. else
  5343. adj = STEP3 + 1;
  5344. count3 = (adj + N32 - N31) / STEP3;
  5345. if (__builtin_expect (N22 cond2 N21, 0)) goto Z0;
  5346. if (cond2 is <)
  5347. adj = STEP2 - 1;
  5348. else
  5349. adj = STEP2 + 1;
  5350. count2 = (adj + N22 - N21) / STEP2;
  5351. if (__builtin_expect (N12 cond1 N11, 0)) goto Z0;
  5352. if (cond1 is <)
  5353. adj = STEP1 - 1;
  5354. else
  5355. adj = STEP1 + 1;
  5356. count1 = (adj + N12 - N11) / STEP1;
  5357. count = count1 * count2 * count3;
  5358. goto Z1;
  5359. Z0:
  5360. count = 0;
  5361. Z1:
  5362. more = GOMP_loop_foo_start (0, count, 1, CHUNK, &istart0, &iend0);
  5363. if (more) goto L0; else goto L3;
  5364. L0:
  5365. V = istart0;
  5366. T = V;
  5367. V3 = N31 + (T % count3) * STEP3;
  5368. T = T / count3;
  5369. V2 = N21 + (T % count2) * STEP2;
  5370. T = T / count2;
  5371. V1 = N11 + T * STEP1;
  5372. iend = iend0;
  5373. L1:
  5374. BODY;
  5375. V += 1;
  5376. if (V < iend) goto L10; else goto L2;
  5377. L10:
  5378. V3 += STEP3;
  5379. if (V3 cond3 N32) goto L1; else goto L11;
  5380. L11:
  5381. V3 = N31;
  5382. V2 += STEP2;
  5383. if (V2 cond2 N22) goto L1; else goto L12;
  5384. L12:
  5385. V2 = N21;
  5386. V1 += STEP1;
  5387. goto L1;
  5388. L2:
  5389. if (GOMP_loop_foo_next (&istart0, &iend0)) goto L0; else goto L3;
  5390. L3:
  5391. */
  5392. static void
  5393. expand_omp_for_generic (struct omp_region *region,
  5394. struct omp_for_data *fd,
  5395. enum built_in_function start_fn,
  5396. enum built_in_function next_fn,
  5397. gimple inner_stmt)
  5398. {
  5399. tree type, istart0, iend0, iend;
  5400. tree t, vmain, vback, bias = NULL_TREE;
  5401. basic_block entry_bb, cont_bb, exit_bb, l0_bb, l1_bb, collapse_bb;
  5402. basic_block l2_bb = NULL, l3_bb = NULL;
  5403. gimple_stmt_iterator gsi;
  5404. gassign *assign_stmt;
  5405. bool in_combined_parallel = is_combined_parallel (region);
  5406. bool broken_loop = region->cont == NULL;
  5407. edge e, ne;
  5408. tree *counts = NULL;
  5409. int i;
  5410. gcc_assert (!broken_loop || !in_combined_parallel);
  5411. gcc_assert (fd->iter_type == long_integer_type_node
  5412. || !in_combined_parallel);
  5413. type = TREE_TYPE (fd->loop.v);
  5414. istart0 = create_tmp_var (fd->iter_type, ".istart0");
  5415. iend0 = create_tmp_var (fd->iter_type, ".iend0");
  5416. TREE_ADDRESSABLE (istart0) = 1;
  5417. TREE_ADDRESSABLE (iend0) = 1;
  5418. /* See if we need to bias by LLONG_MIN. */
  5419. if (fd->iter_type == long_long_unsigned_type_node
  5420. && TREE_CODE (type) == INTEGER_TYPE
  5421. && !TYPE_UNSIGNED (type))
  5422. {
  5423. tree n1, n2;
  5424. if (fd->loop.cond_code == LT_EXPR)
  5425. {
  5426. n1 = fd->loop.n1;
  5427. n2 = fold_build2 (PLUS_EXPR, type, fd->loop.n2, fd->loop.step);
  5428. }
  5429. else
  5430. {
  5431. n1 = fold_build2 (MINUS_EXPR, type, fd->loop.n2, fd->loop.step);
  5432. n2 = fd->loop.n1;
  5433. }
  5434. if (TREE_CODE (n1) != INTEGER_CST
  5435. || TREE_CODE (n2) != INTEGER_CST
  5436. || ((tree_int_cst_sgn (n1) < 0) ^ (tree_int_cst_sgn (n2) < 0)))
  5437. bias = fold_convert (fd->iter_type, TYPE_MIN_VALUE (type));
  5438. }
  5439. entry_bb = region->entry;
  5440. cont_bb = region->cont;
  5441. collapse_bb = NULL;
  5442. gcc_assert (EDGE_COUNT (entry_bb->succs) == 2);
  5443. gcc_assert (broken_loop
  5444. || BRANCH_EDGE (entry_bb)->dest == FALLTHRU_EDGE (cont_bb)->dest);
  5445. l0_bb = split_edge (FALLTHRU_EDGE (entry_bb));
  5446. l1_bb = single_succ (l0_bb);
  5447. if (!broken_loop)
  5448. {
  5449. l2_bb = create_empty_bb (cont_bb);
  5450. gcc_assert (BRANCH_EDGE (cont_bb)->dest == l1_bb);
  5451. gcc_assert (EDGE_COUNT (cont_bb->succs) == 2);
  5452. }
  5453. else
  5454. l2_bb = NULL;
  5455. l3_bb = BRANCH_EDGE (entry_bb)->dest;
  5456. exit_bb = region->exit;
  5457. gsi = gsi_last_bb (entry_bb);
  5458. gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_FOR);
  5459. if (fd->collapse > 1)
  5460. {
  5461. int first_zero_iter = -1;
  5462. basic_block zero_iter_bb = NULL, l2_dom_bb = NULL;
  5463. counts = XALLOCAVEC (tree, fd->collapse);
  5464. expand_omp_for_init_counts (fd, &gsi, entry_bb, counts,
  5465. zero_iter_bb, first_zero_iter,
  5466. l2_dom_bb);
  5467. if (zero_iter_bb)
  5468. {
  5469. /* Some counts[i] vars might be uninitialized if
  5470. some loop has zero iterations. But the body shouldn't
  5471. be executed in that case, so just avoid uninit warnings. */
  5472. for (i = first_zero_iter; i < fd->collapse; i++)
  5473. if (SSA_VAR_P (counts[i]))
  5474. TREE_NO_WARNING (counts[i]) = 1;
  5475. gsi_prev (&gsi);
  5476. e = split_block (entry_bb, gsi_stmt (gsi));
  5477. entry_bb = e->dest;
  5478. make_edge (zero_iter_bb, entry_bb, EDGE_FALLTHRU);
  5479. gsi = gsi_last_bb (entry_bb);
  5480. set_immediate_dominator (CDI_DOMINATORS, entry_bb,
  5481. get_immediate_dominator (CDI_DOMINATORS,
  5482. zero_iter_bb));
  5483. }
  5484. }
  5485. if (in_combined_parallel)
  5486. {
  5487. /* In a combined parallel loop, emit a call to
  5488. GOMP_loop_foo_next. */
  5489. t = build_call_expr (builtin_decl_explicit (next_fn), 2,
  5490. build_fold_addr_expr (istart0),
  5491. build_fold_addr_expr (iend0));
  5492. }
  5493. else
  5494. {
  5495. tree t0, t1, t2, t3, t4;
  5496. /* If this is not a combined parallel loop, emit a call to
  5497. GOMP_loop_foo_start in ENTRY_BB. */
  5498. t4 = build_fold_addr_expr (iend0);
  5499. t3 = build_fold_addr_expr (istart0);
  5500. t2 = fold_convert (fd->iter_type, fd->loop.step);
  5501. t1 = fd->loop.n2;
  5502. t0 = fd->loop.n1;
  5503. if (gimple_omp_for_combined_into_p (fd->for_stmt))
  5504. {
  5505. tree innerc = find_omp_clause (gimple_omp_for_clauses (fd->for_stmt),
  5506. OMP_CLAUSE__LOOPTEMP_);
  5507. gcc_assert (innerc);
  5508. t0 = OMP_CLAUSE_DECL (innerc);
  5509. innerc = find_omp_clause (OMP_CLAUSE_CHAIN (innerc),
  5510. OMP_CLAUSE__LOOPTEMP_);
  5511. gcc_assert (innerc);
  5512. t1 = OMP_CLAUSE_DECL (innerc);
  5513. }
  5514. if (POINTER_TYPE_P (TREE_TYPE (t0))
  5515. && TYPE_PRECISION (TREE_TYPE (t0))
  5516. != TYPE_PRECISION (fd->iter_type))
  5517. {
  5518. /* Avoid casting pointers to integer of a different size. */
  5519. tree itype = signed_type_for (type);
  5520. t1 = fold_convert (fd->iter_type, fold_convert (itype, t1));
  5521. t0 = fold_convert (fd->iter_type, fold_convert (itype, t0));
  5522. }
  5523. else
  5524. {
  5525. t1 = fold_convert (fd->iter_type, t1);
  5526. t0 = fold_convert (fd->iter_type, t0);
  5527. }
  5528. if (bias)
  5529. {
  5530. t1 = fold_build2 (PLUS_EXPR, fd->iter_type, t1, bias);
  5531. t0 = fold_build2 (PLUS_EXPR, fd->iter_type, t0, bias);
  5532. }
  5533. if (fd->iter_type == long_integer_type_node)
  5534. {
  5535. if (fd->chunk_size)
  5536. {
  5537. t = fold_convert (fd->iter_type, fd->chunk_size);
  5538. t = build_call_expr (builtin_decl_explicit (start_fn),
  5539. 6, t0, t1, t2, t, t3, t4);
  5540. }
  5541. else
  5542. t = build_call_expr (builtin_decl_explicit (start_fn),
  5543. 5, t0, t1, t2, t3, t4);
  5544. }
  5545. else
  5546. {
  5547. tree t5;
  5548. tree c_bool_type;
  5549. tree bfn_decl;
  5550. /* The GOMP_loop_ull_*start functions have additional boolean
  5551. argument, true for < loops and false for > loops.
  5552. In Fortran, the C bool type can be different from
  5553. boolean_type_node. */
  5554. bfn_decl = builtin_decl_explicit (start_fn);
  5555. c_bool_type = TREE_TYPE (TREE_TYPE (bfn_decl));
  5556. t5 = build_int_cst (c_bool_type,
  5557. fd->loop.cond_code == LT_EXPR ? 1 : 0);
  5558. if (fd->chunk_size)
  5559. {
  5560. tree bfn_decl = builtin_decl_explicit (start_fn);
  5561. t = fold_convert (fd->iter_type, fd->chunk_size);
  5562. t = build_call_expr (bfn_decl, 7, t5, t0, t1, t2, t, t3, t4);
  5563. }
  5564. else
  5565. t = build_call_expr (builtin_decl_explicit (start_fn),
  5566. 6, t5, t0, t1, t2, t3, t4);
  5567. }
  5568. }
  5569. if (TREE_TYPE (t) != boolean_type_node)
  5570. t = fold_build2 (NE_EXPR, boolean_type_node,
  5571. t, build_int_cst (TREE_TYPE (t), 0));
  5572. t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
  5573. true, GSI_SAME_STMT);
  5574. gsi_insert_after (&gsi, gimple_build_cond_empty (t), GSI_SAME_STMT);
  5575. /* Remove the GIMPLE_OMP_FOR statement. */
  5576. gsi_remove (&gsi, true);
  5577. /* Iteration setup for sequential loop goes in L0_BB. */
  5578. tree startvar = fd->loop.v;
  5579. tree endvar = NULL_TREE;
  5580. if (gimple_omp_for_combined_p (fd->for_stmt))
  5581. {
  5582. gcc_assert (gimple_code (inner_stmt) == GIMPLE_OMP_FOR
  5583. && gimple_omp_for_kind (inner_stmt)
  5584. == GF_OMP_FOR_KIND_SIMD);
  5585. tree innerc = find_omp_clause (gimple_omp_for_clauses (inner_stmt),
  5586. OMP_CLAUSE__LOOPTEMP_);
  5587. gcc_assert (innerc);
  5588. startvar = OMP_CLAUSE_DECL (innerc);
  5589. innerc = find_omp_clause (OMP_CLAUSE_CHAIN (innerc),
  5590. OMP_CLAUSE__LOOPTEMP_);
  5591. gcc_assert (innerc);
  5592. endvar = OMP_CLAUSE_DECL (innerc);
  5593. }
  5594. gsi = gsi_start_bb (l0_bb);
  5595. t = istart0;
  5596. if (bias)
  5597. t = fold_build2 (MINUS_EXPR, fd->iter_type, t, bias);
  5598. if (POINTER_TYPE_P (TREE_TYPE (startvar)))
  5599. t = fold_convert (signed_type_for (TREE_TYPE (startvar)), t);
  5600. t = fold_convert (TREE_TYPE (startvar), t);
  5601. t = force_gimple_operand_gsi (&gsi, t,
  5602. DECL_P (startvar)
  5603. && TREE_ADDRESSABLE (startvar),
  5604. NULL_TREE, false, GSI_CONTINUE_LINKING);
  5605. assign_stmt = gimple_build_assign (startvar, t);
  5606. gsi_insert_after (&gsi, assign_stmt, GSI_CONTINUE_LINKING);
  5607. t = iend0;
  5608. if (bias)
  5609. t = fold_build2 (MINUS_EXPR, fd->iter_type, t, bias);
  5610. if (POINTER_TYPE_P (TREE_TYPE (startvar)))
  5611. t = fold_convert (signed_type_for (TREE_TYPE (startvar)), t);
  5612. t = fold_convert (TREE_TYPE (startvar), t);
  5613. iend = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
  5614. false, GSI_CONTINUE_LINKING);
  5615. if (endvar)
  5616. {
  5617. assign_stmt = gimple_build_assign (endvar, iend);
  5618. gsi_insert_after (&gsi, assign_stmt, GSI_CONTINUE_LINKING);
  5619. if (useless_type_conversion_p (TREE_TYPE (fd->loop.v), TREE_TYPE (iend)))
  5620. assign_stmt = gimple_build_assign (fd->loop.v, iend);
  5621. else
  5622. assign_stmt = gimple_build_assign (fd->loop.v, NOP_EXPR, iend);
  5623. gsi_insert_after (&gsi, assign_stmt, GSI_CONTINUE_LINKING);
  5624. }
  5625. if (fd->collapse > 1)
  5626. expand_omp_for_init_vars (fd, &gsi, counts, inner_stmt, startvar);
  5627. if (!broken_loop)
  5628. {
  5629. /* Code to control the increment and predicate for the sequential
  5630. loop goes in the CONT_BB. */
  5631. gsi = gsi_last_bb (cont_bb);
  5632. gomp_continue *cont_stmt = as_a <gomp_continue *> (gsi_stmt (gsi));
  5633. gcc_assert (gimple_code (cont_stmt) == GIMPLE_OMP_CONTINUE);
  5634. vmain = gimple_omp_continue_control_use (cont_stmt);
  5635. vback = gimple_omp_continue_control_def (cont_stmt);
  5636. if (!gimple_omp_for_combined_p (fd->for_stmt))
  5637. {
  5638. if (POINTER_TYPE_P (type))
  5639. t = fold_build_pointer_plus (vmain, fd->loop.step);
  5640. else
  5641. t = fold_build2 (PLUS_EXPR, type, vmain, fd->loop.step);
  5642. t = force_gimple_operand_gsi (&gsi, t,
  5643. DECL_P (vback)
  5644. && TREE_ADDRESSABLE (vback),
  5645. NULL_TREE, true, GSI_SAME_STMT);
  5646. assign_stmt = gimple_build_assign (vback, t);
  5647. gsi_insert_before (&gsi, assign_stmt, GSI_SAME_STMT);
  5648. t = build2 (fd->loop.cond_code, boolean_type_node,
  5649. DECL_P (vback) && TREE_ADDRESSABLE (vback) ? t : vback,
  5650. iend);
  5651. gcond *cond_stmt = gimple_build_cond_empty (t);
  5652. gsi_insert_before (&gsi, cond_stmt, GSI_SAME_STMT);
  5653. }
  5654. /* Remove GIMPLE_OMP_CONTINUE. */
  5655. gsi_remove (&gsi, true);
  5656. if (fd->collapse > 1 && !gimple_omp_for_combined_p (fd->for_stmt))
  5657. collapse_bb = extract_omp_for_update_vars (fd, cont_bb, l1_bb);
  5658. /* Emit code to get the next parallel iteration in L2_BB. */
  5659. gsi = gsi_start_bb (l2_bb);
  5660. t = build_call_expr (builtin_decl_explicit (next_fn), 2,
  5661. build_fold_addr_expr (istart0),
  5662. build_fold_addr_expr (iend0));
  5663. t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
  5664. false, GSI_CONTINUE_LINKING);
  5665. if (TREE_TYPE (t) != boolean_type_node)
  5666. t = fold_build2 (NE_EXPR, boolean_type_node,
  5667. t, build_int_cst (TREE_TYPE (t), 0));
  5668. gcond *cond_stmt = gimple_build_cond_empty (t);
  5669. gsi_insert_after (&gsi, cond_stmt, GSI_CONTINUE_LINKING);
  5670. }
  5671. /* Add the loop cleanup function. */
  5672. gsi = gsi_last_bb (exit_bb);
  5673. if (gimple_omp_return_nowait_p (gsi_stmt (gsi)))
  5674. t = builtin_decl_explicit (BUILT_IN_GOMP_LOOP_END_NOWAIT);
  5675. else if (gimple_omp_return_lhs (gsi_stmt (gsi)))
  5676. t = builtin_decl_explicit (BUILT_IN_GOMP_LOOP_END_CANCEL);
  5677. else
  5678. t = builtin_decl_explicit (BUILT_IN_GOMP_LOOP_END);
  5679. gcall *call_stmt = gimple_build_call (t, 0);
  5680. if (gimple_omp_return_lhs (gsi_stmt (gsi)))
  5681. gimple_call_set_lhs (call_stmt, gimple_omp_return_lhs (gsi_stmt (gsi)));
  5682. gsi_insert_after (&gsi, call_stmt, GSI_SAME_STMT);
  5683. gsi_remove (&gsi, true);
  5684. /* Connect the new blocks. */
  5685. find_edge (entry_bb, l0_bb)->flags = EDGE_TRUE_VALUE;
  5686. find_edge (entry_bb, l3_bb)->flags = EDGE_FALSE_VALUE;
  5687. if (!broken_loop)
  5688. {
  5689. gimple_seq phis;
  5690. e = find_edge (cont_bb, l3_bb);
  5691. ne = make_edge (l2_bb, l3_bb, EDGE_FALSE_VALUE);
  5692. phis = phi_nodes (l3_bb);
  5693. for (gsi = gsi_start (phis); !gsi_end_p (gsi); gsi_next (&gsi))
  5694. {
  5695. gimple phi = gsi_stmt (gsi);
  5696. SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (phi, ne),
  5697. PHI_ARG_DEF_FROM_EDGE (phi, e));
  5698. }
  5699. remove_edge (e);
  5700. make_edge (cont_bb, l2_bb, EDGE_FALSE_VALUE);
  5701. add_bb_to_loop (l2_bb, cont_bb->loop_father);
  5702. e = find_edge (cont_bb, l1_bb);
  5703. if (gimple_omp_for_combined_p (fd->for_stmt))
  5704. {
  5705. remove_edge (e);
  5706. e = NULL;
  5707. }
  5708. else if (fd->collapse > 1)
  5709. {
  5710. remove_edge (e);
  5711. e = make_edge (cont_bb, collapse_bb, EDGE_TRUE_VALUE);
  5712. }
  5713. else
  5714. e->flags = EDGE_TRUE_VALUE;
  5715. if (e)
  5716. {
  5717. e->probability = REG_BR_PROB_BASE * 7 / 8;
  5718. find_edge (cont_bb, l2_bb)->probability = REG_BR_PROB_BASE / 8;
  5719. }
  5720. else
  5721. {
  5722. e = find_edge (cont_bb, l2_bb);
  5723. e->flags = EDGE_FALLTHRU;
  5724. }
  5725. make_edge (l2_bb, l0_bb, EDGE_TRUE_VALUE);
  5726. set_immediate_dominator (CDI_DOMINATORS, l2_bb,
  5727. recompute_dominator (CDI_DOMINATORS, l2_bb));
  5728. set_immediate_dominator (CDI_DOMINATORS, l3_bb,
  5729. recompute_dominator (CDI_DOMINATORS, l3_bb));
  5730. set_immediate_dominator (CDI_DOMINATORS, l0_bb,
  5731. recompute_dominator (CDI_DOMINATORS, l0_bb));
  5732. set_immediate_dominator (CDI_DOMINATORS, l1_bb,
  5733. recompute_dominator (CDI_DOMINATORS, l1_bb));
  5734. struct loop *outer_loop = alloc_loop ();
  5735. outer_loop->header = l0_bb;
  5736. outer_loop->latch = l2_bb;
  5737. add_loop (outer_loop, l0_bb->loop_father);
  5738. if (!gimple_omp_for_combined_p (fd->for_stmt))
  5739. {
  5740. struct loop *loop = alloc_loop ();
  5741. loop->header = l1_bb;
  5742. /* The loop may have multiple latches. */
  5743. add_loop (loop, outer_loop);
  5744. }
  5745. }
  5746. }
  5747. /* A subroutine of expand_omp_for. Generate code for a parallel
  5748. loop with static schedule and no specified chunk size. Given
  5749. parameters:
  5750. for (V = N1; V cond N2; V += STEP) BODY;
  5751. where COND is "<" or ">", we generate pseudocode
  5752. if ((__typeof (V)) -1 > 0 && N2 cond N1) goto L2;
  5753. if (cond is <)
  5754. adj = STEP - 1;
  5755. else
  5756. adj = STEP + 1;
  5757. if ((__typeof (V)) -1 > 0 && cond is >)
  5758. n = -(adj + N2 - N1) / -STEP;
  5759. else
  5760. n = (adj + N2 - N1) / STEP;
  5761. q = n / nthreads;
  5762. tt = n % nthreads;
  5763. if (threadid < tt) goto L3; else goto L4;
  5764. L3:
  5765. tt = 0;
  5766. q = q + 1;
  5767. L4:
  5768. s0 = q * threadid + tt;
  5769. e0 = s0 + q;
  5770. V = s0 * STEP + N1;
  5771. if (s0 >= e0) goto L2; else goto L0;
  5772. L0:
  5773. e = e0 * STEP + N1;
  5774. L1:
  5775. BODY;
  5776. V += STEP;
  5777. if (V cond e) goto L1;
  5778. L2:
  5779. */
  5780. static void
  5781. expand_omp_for_static_nochunk (struct omp_region *region,
  5782. struct omp_for_data *fd,
  5783. gimple inner_stmt)
  5784. {
  5785. tree n, q, s0, e0, e, t, tt, nthreads, threadid;
  5786. tree type, itype, vmain, vback;
  5787. basic_block entry_bb, second_bb, third_bb, exit_bb, seq_start_bb;
  5788. basic_block body_bb, cont_bb, collapse_bb = NULL;
  5789. basic_block fin_bb;
  5790. gimple_stmt_iterator gsi;
  5791. edge ep;
  5792. bool broken_loop = region->cont == NULL;
  5793. tree *counts = NULL;
  5794. tree n1, n2, step;
  5795. gcc_checking_assert ((gimple_omp_for_kind (fd->for_stmt)
  5796. != GF_OMP_FOR_KIND_OACC_LOOP)
  5797. || !inner_stmt);
  5798. itype = type = TREE_TYPE (fd->loop.v);
  5799. if (POINTER_TYPE_P (type))
  5800. itype = signed_type_for (type);
  5801. entry_bb = region->entry;
  5802. cont_bb = region->cont;
  5803. gcc_assert (EDGE_COUNT (entry_bb->succs) == 2);
  5804. fin_bb = BRANCH_EDGE (entry_bb)->dest;
  5805. gcc_assert (broken_loop
  5806. || (fin_bb == FALLTHRU_EDGE (cont_bb)->dest));
  5807. seq_start_bb = split_edge (FALLTHRU_EDGE (entry_bb));
  5808. body_bb = single_succ (seq_start_bb);
  5809. if (!broken_loop)
  5810. {
  5811. gcc_assert (BRANCH_EDGE (cont_bb)->dest == body_bb);
  5812. gcc_assert (EDGE_COUNT (cont_bb->succs) == 2);
  5813. }
  5814. exit_bb = region->exit;
  5815. /* Iteration space partitioning goes in ENTRY_BB. */
  5816. gsi = gsi_last_bb (entry_bb);
  5817. gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_FOR);
  5818. if (fd->collapse > 1)
  5819. {
  5820. int first_zero_iter = -1;
  5821. basic_block l2_dom_bb = NULL;
  5822. counts = XALLOCAVEC (tree, fd->collapse);
  5823. expand_omp_for_init_counts (fd, &gsi, entry_bb, counts,
  5824. fin_bb, first_zero_iter,
  5825. l2_dom_bb);
  5826. t = NULL_TREE;
  5827. }
  5828. else if (gimple_omp_for_combined_into_p (fd->for_stmt))
  5829. t = integer_one_node;
  5830. else
  5831. t = fold_binary (fd->loop.cond_code, boolean_type_node,
  5832. fold_convert (type, fd->loop.n1),
  5833. fold_convert (type, fd->loop.n2));
  5834. if (fd->collapse == 1
  5835. && TYPE_UNSIGNED (type)
  5836. && (t == NULL_TREE || !integer_onep (t)))
  5837. {
  5838. n1 = fold_convert (type, unshare_expr (fd->loop.n1));
  5839. n1 = force_gimple_operand_gsi (&gsi, n1, true, NULL_TREE,
  5840. true, GSI_SAME_STMT);
  5841. n2 = fold_convert (type, unshare_expr (fd->loop.n2));
  5842. n2 = force_gimple_operand_gsi (&gsi, n2, true, NULL_TREE,
  5843. true, GSI_SAME_STMT);
  5844. gcond *cond_stmt = gimple_build_cond (fd->loop.cond_code, n1, n2,
  5845. NULL_TREE, NULL_TREE);
  5846. gsi_insert_before (&gsi, cond_stmt, GSI_SAME_STMT);
  5847. if (walk_tree (gimple_cond_lhs_ptr (cond_stmt),
  5848. expand_omp_regimplify_p, NULL, NULL)
  5849. || walk_tree (gimple_cond_rhs_ptr (cond_stmt),
  5850. expand_omp_regimplify_p, NULL, NULL))
  5851. {
  5852. gsi = gsi_for_stmt (cond_stmt);
  5853. gimple_regimplify_operands (cond_stmt, &gsi);
  5854. }
  5855. ep = split_block (entry_bb, cond_stmt);
  5856. ep->flags = EDGE_TRUE_VALUE;
  5857. entry_bb = ep->dest;
  5858. ep->probability = REG_BR_PROB_BASE - (REG_BR_PROB_BASE / 2000 - 1);
  5859. ep = make_edge (ep->src, fin_bb, EDGE_FALSE_VALUE);
  5860. ep->probability = REG_BR_PROB_BASE / 2000 - 1;
  5861. if (gimple_in_ssa_p (cfun))
  5862. {
  5863. int dest_idx = find_edge (entry_bb, fin_bb)->dest_idx;
  5864. for (gphi_iterator gpi = gsi_start_phis (fin_bb);
  5865. !gsi_end_p (gpi); gsi_next (&gpi))
  5866. {
  5867. gphi *phi = gpi.phi ();
  5868. add_phi_arg (phi, gimple_phi_arg_def (phi, dest_idx),
  5869. ep, UNKNOWN_LOCATION);
  5870. }
  5871. }
  5872. gsi = gsi_last_bb (entry_bb);
  5873. }
  5874. switch (gimple_omp_for_kind (fd->for_stmt))
  5875. {
  5876. case GF_OMP_FOR_KIND_FOR:
  5877. nthreads = builtin_decl_explicit (BUILT_IN_OMP_GET_NUM_THREADS);
  5878. threadid = builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM);
  5879. break;
  5880. case GF_OMP_FOR_KIND_DISTRIBUTE:
  5881. nthreads = builtin_decl_explicit (BUILT_IN_OMP_GET_NUM_TEAMS);
  5882. threadid = builtin_decl_explicit (BUILT_IN_OMP_GET_TEAM_NUM);
  5883. break;
  5884. case GF_OMP_FOR_KIND_OACC_LOOP:
  5885. nthreads = builtin_decl_explicit (BUILT_IN_GOACC_GET_NUM_THREADS);
  5886. threadid = builtin_decl_explicit (BUILT_IN_GOACC_GET_THREAD_NUM);
  5887. break;
  5888. default:
  5889. gcc_unreachable ();
  5890. }
  5891. nthreads = build_call_expr (nthreads, 0);
  5892. nthreads = fold_convert (itype, nthreads);
  5893. nthreads = force_gimple_operand_gsi (&gsi, nthreads, true, NULL_TREE,
  5894. true, GSI_SAME_STMT);
  5895. threadid = build_call_expr (threadid, 0);
  5896. threadid = fold_convert (itype, threadid);
  5897. threadid = force_gimple_operand_gsi (&gsi, threadid, true, NULL_TREE,
  5898. true, GSI_SAME_STMT);
  5899. n1 = fd->loop.n1;
  5900. n2 = fd->loop.n2;
  5901. step = fd->loop.step;
  5902. if (gimple_omp_for_combined_into_p (fd->for_stmt))
  5903. {
  5904. tree innerc = find_omp_clause (gimple_omp_for_clauses (fd->for_stmt),
  5905. OMP_CLAUSE__LOOPTEMP_);
  5906. gcc_assert (innerc);
  5907. n1 = OMP_CLAUSE_DECL (innerc);
  5908. innerc = find_omp_clause (OMP_CLAUSE_CHAIN (innerc),
  5909. OMP_CLAUSE__LOOPTEMP_);
  5910. gcc_assert (innerc);
  5911. n2 = OMP_CLAUSE_DECL (innerc);
  5912. }
  5913. n1 = force_gimple_operand_gsi (&gsi, fold_convert (type, n1),
  5914. true, NULL_TREE, true, GSI_SAME_STMT);
  5915. n2 = force_gimple_operand_gsi (&gsi, fold_convert (itype, n2),
  5916. true, NULL_TREE, true, GSI_SAME_STMT);
  5917. step = force_gimple_operand_gsi (&gsi, fold_convert (itype, step),
  5918. true, NULL_TREE, true, GSI_SAME_STMT);
  5919. t = build_int_cst (itype, (fd->loop.cond_code == LT_EXPR ? -1 : 1));
  5920. t = fold_build2 (PLUS_EXPR, itype, step, t);
  5921. t = fold_build2 (PLUS_EXPR, itype, t, n2);
  5922. t = fold_build2 (MINUS_EXPR, itype, t, fold_convert (itype, n1));
  5923. if (TYPE_UNSIGNED (itype) && fd->loop.cond_code == GT_EXPR)
  5924. t = fold_build2 (TRUNC_DIV_EXPR, itype,
  5925. fold_build1 (NEGATE_EXPR, itype, t),
  5926. fold_build1 (NEGATE_EXPR, itype, step));
  5927. else
  5928. t = fold_build2 (TRUNC_DIV_EXPR, itype, t, step);
  5929. t = fold_convert (itype, t);
  5930. n = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE, true, GSI_SAME_STMT);
  5931. q = create_tmp_reg (itype, "q");
  5932. t = fold_build2 (TRUNC_DIV_EXPR, itype, n, nthreads);
  5933. t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE, true, GSI_SAME_STMT);
  5934. gsi_insert_before (&gsi, gimple_build_assign (q, t), GSI_SAME_STMT);
  5935. tt = create_tmp_reg (itype, "tt");
  5936. t = fold_build2 (TRUNC_MOD_EXPR, itype, n, nthreads);
  5937. t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE, true, GSI_SAME_STMT);
  5938. gsi_insert_before (&gsi, gimple_build_assign (tt, t), GSI_SAME_STMT);
  5939. t = build2 (LT_EXPR, boolean_type_node, threadid, tt);
  5940. gcond *cond_stmt = gimple_build_cond_empty (t);
  5941. gsi_insert_before (&gsi, cond_stmt, GSI_SAME_STMT);
  5942. second_bb = split_block (entry_bb, cond_stmt)->dest;
  5943. gsi = gsi_last_bb (second_bb);
  5944. gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_FOR);
  5945. gsi_insert_before (&gsi, gimple_build_assign (tt, build_int_cst (itype, 0)),
  5946. GSI_SAME_STMT);
  5947. gassign *assign_stmt
  5948. = gimple_build_assign (q, PLUS_EXPR, q, build_int_cst (itype, 1));
  5949. gsi_insert_before (&gsi, assign_stmt, GSI_SAME_STMT);
  5950. third_bb = split_block (second_bb, assign_stmt)->dest;
  5951. gsi = gsi_last_bb (third_bb);
  5952. gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_FOR);
  5953. t = build2 (MULT_EXPR, itype, q, threadid);
  5954. t = build2 (PLUS_EXPR, itype, t, tt);
  5955. s0 = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE, true, GSI_SAME_STMT);
  5956. t = fold_build2 (PLUS_EXPR, itype, s0, q);
  5957. e0 = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE, true, GSI_SAME_STMT);
  5958. t = build2 (GE_EXPR, boolean_type_node, s0, e0);
  5959. gsi_insert_before (&gsi, gimple_build_cond_empty (t), GSI_SAME_STMT);
  5960. /* Remove the GIMPLE_OMP_FOR statement. */
  5961. gsi_remove (&gsi, true);
  5962. /* Setup code for sequential iteration goes in SEQ_START_BB. */
  5963. gsi = gsi_start_bb (seq_start_bb);
  5964. tree startvar = fd->loop.v;
  5965. tree endvar = NULL_TREE;
  5966. if (gimple_omp_for_combined_p (fd->for_stmt))
  5967. {
  5968. tree clauses = gimple_code (inner_stmt) == GIMPLE_OMP_PARALLEL
  5969. ? gimple_omp_parallel_clauses (inner_stmt)
  5970. : gimple_omp_for_clauses (inner_stmt);
  5971. tree innerc = find_omp_clause (clauses, OMP_CLAUSE__LOOPTEMP_);
  5972. gcc_assert (innerc);
  5973. startvar = OMP_CLAUSE_DECL (innerc);
  5974. innerc = find_omp_clause (OMP_CLAUSE_CHAIN (innerc),
  5975. OMP_CLAUSE__LOOPTEMP_);
  5976. gcc_assert (innerc);
  5977. endvar = OMP_CLAUSE_DECL (innerc);
  5978. }
  5979. t = fold_convert (itype, s0);
  5980. t = fold_build2 (MULT_EXPR, itype, t, step);
  5981. if (POINTER_TYPE_P (type))
  5982. t = fold_build_pointer_plus (n1, t);
  5983. else
  5984. t = fold_build2 (PLUS_EXPR, type, t, n1);
  5985. t = fold_convert (TREE_TYPE (startvar), t);
  5986. t = force_gimple_operand_gsi (&gsi, t,
  5987. DECL_P (startvar)
  5988. && TREE_ADDRESSABLE (startvar),
  5989. NULL_TREE, false, GSI_CONTINUE_LINKING);
  5990. assign_stmt = gimple_build_assign (startvar, t);
  5991. gsi_insert_after (&gsi, assign_stmt, GSI_CONTINUE_LINKING);
  5992. t = fold_convert (itype, e0);
  5993. t = fold_build2 (MULT_EXPR, itype, t, step);
  5994. if (POINTER_TYPE_P (type))
  5995. t = fold_build_pointer_plus (n1, t);
  5996. else
  5997. t = fold_build2 (PLUS_EXPR, type, t, n1);
  5998. t = fold_convert (TREE_TYPE (startvar), t);
  5999. e = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
  6000. false, GSI_CONTINUE_LINKING);
  6001. if (endvar)
  6002. {
  6003. assign_stmt = gimple_build_assign (endvar, e);
  6004. gsi_insert_after (&gsi, assign_stmt, GSI_CONTINUE_LINKING);
  6005. if (useless_type_conversion_p (TREE_TYPE (fd->loop.v), TREE_TYPE (e)))
  6006. assign_stmt = gimple_build_assign (fd->loop.v, e);
  6007. else
  6008. assign_stmt = gimple_build_assign (fd->loop.v, NOP_EXPR, e);
  6009. gsi_insert_after (&gsi, assign_stmt, GSI_CONTINUE_LINKING);
  6010. }
  6011. if (fd->collapse > 1)
  6012. expand_omp_for_init_vars (fd, &gsi, counts, inner_stmt, startvar);
  6013. if (!broken_loop)
  6014. {
  6015. /* The code controlling the sequential loop replaces the
  6016. GIMPLE_OMP_CONTINUE. */
  6017. gsi = gsi_last_bb (cont_bb);
  6018. gomp_continue *cont_stmt = as_a <gomp_continue *> (gsi_stmt (gsi));
  6019. gcc_assert (gimple_code (cont_stmt) == GIMPLE_OMP_CONTINUE);
  6020. vmain = gimple_omp_continue_control_use (cont_stmt);
  6021. vback = gimple_omp_continue_control_def (cont_stmt);
  6022. if (!gimple_omp_for_combined_p (fd->for_stmt))
  6023. {
  6024. if (POINTER_TYPE_P (type))
  6025. t = fold_build_pointer_plus (vmain, step);
  6026. else
  6027. t = fold_build2 (PLUS_EXPR, type, vmain, step);
  6028. t = force_gimple_operand_gsi (&gsi, t,
  6029. DECL_P (vback)
  6030. && TREE_ADDRESSABLE (vback),
  6031. NULL_TREE, true, GSI_SAME_STMT);
  6032. assign_stmt = gimple_build_assign (vback, t);
  6033. gsi_insert_before (&gsi, assign_stmt, GSI_SAME_STMT);
  6034. t = build2 (fd->loop.cond_code, boolean_type_node,
  6035. DECL_P (vback) && TREE_ADDRESSABLE (vback)
  6036. ? t : vback, e);
  6037. gsi_insert_before (&gsi, gimple_build_cond_empty (t), GSI_SAME_STMT);
  6038. }
  6039. /* Remove the GIMPLE_OMP_CONTINUE statement. */
  6040. gsi_remove (&gsi, true);
  6041. if (fd->collapse > 1 && !gimple_omp_for_combined_p (fd->for_stmt))
  6042. collapse_bb = extract_omp_for_update_vars (fd, cont_bb, body_bb);
  6043. }
  6044. /* Replace the GIMPLE_OMP_RETURN with a barrier, or nothing. */
  6045. gsi = gsi_last_bb (exit_bb);
  6046. if (!gimple_omp_return_nowait_p (gsi_stmt (gsi)))
  6047. {
  6048. t = gimple_omp_return_lhs (gsi_stmt (gsi));
  6049. if (gimple_omp_for_kind (fd->for_stmt) == GF_OMP_FOR_KIND_OACC_LOOP)
  6050. gcc_checking_assert (t == NULL_TREE);
  6051. else
  6052. gsi_insert_after (&gsi, build_omp_barrier (t), GSI_SAME_STMT);
  6053. }
  6054. gsi_remove (&gsi, true);
  6055. /* Connect all the blocks. */
  6056. ep = make_edge (entry_bb, third_bb, EDGE_FALSE_VALUE);
  6057. ep->probability = REG_BR_PROB_BASE / 4 * 3;
  6058. ep = find_edge (entry_bb, second_bb);
  6059. ep->flags = EDGE_TRUE_VALUE;
  6060. ep->probability = REG_BR_PROB_BASE / 4;
  6061. find_edge (third_bb, seq_start_bb)->flags = EDGE_FALSE_VALUE;
  6062. find_edge (third_bb, fin_bb)->flags = EDGE_TRUE_VALUE;
  6063. if (!broken_loop)
  6064. {
  6065. ep = find_edge (cont_bb, body_bb);
  6066. if (gimple_omp_for_combined_p (fd->for_stmt))
  6067. {
  6068. remove_edge (ep);
  6069. ep = NULL;
  6070. }
  6071. else if (fd->collapse > 1)
  6072. {
  6073. remove_edge (ep);
  6074. ep = make_edge (cont_bb, collapse_bb, EDGE_TRUE_VALUE);
  6075. }
  6076. else
  6077. ep->flags = EDGE_TRUE_VALUE;
  6078. find_edge (cont_bb, fin_bb)->flags
  6079. = ep ? EDGE_FALSE_VALUE : EDGE_FALLTHRU;
  6080. }
  6081. set_immediate_dominator (CDI_DOMINATORS, second_bb, entry_bb);
  6082. set_immediate_dominator (CDI_DOMINATORS, third_bb, entry_bb);
  6083. set_immediate_dominator (CDI_DOMINATORS, seq_start_bb, third_bb);
  6084. set_immediate_dominator (CDI_DOMINATORS, body_bb,
  6085. recompute_dominator (CDI_DOMINATORS, body_bb));
  6086. set_immediate_dominator (CDI_DOMINATORS, fin_bb,
  6087. recompute_dominator (CDI_DOMINATORS, fin_bb));
  6088. if (!broken_loop && !gimple_omp_for_combined_p (fd->for_stmt))
  6089. {
  6090. struct loop *loop = alloc_loop ();
  6091. loop->header = body_bb;
  6092. if (collapse_bb == NULL)
  6093. loop->latch = cont_bb;
  6094. add_loop (loop, body_bb->loop_father);
  6095. }
  6096. }
  6097. /* A subroutine of expand_omp_for. Generate code for a parallel
  6098. loop with static schedule and a specified chunk size. Given
  6099. parameters:
  6100. for (V = N1; V cond N2; V += STEP) BODY;
  6101. where COND is "<" or ">", we generate pseudocode
  6102. if ((__typeof (V)) -1 > 0 && N2 cond N1) goto L2;
  6103. if (cond is <)
  6104. adj = STEP - 1;
  6105. else
  6106. adj = STEP + 1;
  6107. if ((__typeof (V)) -1 > 0 && cond is >)
  6108. n = -(adj + N2 - N1) / -STEP;
  6109. else
  6110. n = (adj + N2 - N1) / STEP;
  6111. trip = 0;
  6112. V = threadid * CHUNK * STEP + N1; -- this extra definition of V is
  6113. here so that V is defined
  6114. if the loop is not entered
  6115. L0:
  6116. s0 = (trip * nthreads + threadid) * CHUNK;
  6117. e0 = min(s0 + CHUNK, n);
  6118. if (s0 < n) goto L1; else goto L4;
  6119. L1:
  6120. V = s0 * STEP + N1;
  6121. e = e0 * STEP + N1;
  6122. L2:
  6123. BODY;
  6124. V += STEP;
  6125. if (V cond e) goto L2; else goto L3;
  6126. L3:
  6127. trip += 1;
  6128. goto L0;
  6129. L4:
  6130. */
  6131. static void
  6132. expand_omp_for_static_chunk (struct omp_region *region,
  6133. struct omp_for_data *fd, gimple inner_stmt)
  6134. {
  6135. tree n, s0, e0, e, t;
  6136. tree trip_var, trip_init, trip_main, trip_back, nthreads, threadid;
  6137. tree type, itype, vmain, vback, vextra;
  6138. basic_block entry_bb, exit_bb, body_bb, seq_start_bb, iter_part_bb;
  6139. basic_block trip_update_bb = NULL, cont_bb, collapse_bb = NULL, fin_bb;
  6140. gimple_stmt_iterator gsi;
  6141. edge se;
  6142. bool broken_loop = region->cont == NULL;
  6143. tree *counts = NULL;
  6144. tree n1, n2, step;
  6145. gcc_checking_assert ((gimple_omp_for_kind (fd->for_stmt)
  6146. != GF_OMP_FOR_KIND_OACC_LOOP)
  6147. || !inner_stmt);
  6148. itype = type = TREE_TYPE (fd->loop.v);
  6149. if (POINTER_TYPE_P (type))
  6150. itype = signed_type_for (type);
  6151. entry_bb = region->entry;
  6152. se = split_block (entry_bb, last_stmt (entry_bb));
  6153. entry_bb = se->src;
  6154. iter_part_bb = se->dest;
  6155. cont_bb = region->cont;
  6156. gcc_assert (EDGE_COUNT (iter_part_bb->succs) == 2);
  6157. fin_bb = BRANCH_EDGE (iter_part_bb)->dest;
  6158. gcc_assert (broken_loop
  6159. || fin_bb == FALLTHRU_EDGE (cont_bb)->dest);
  6160. seq_start_bb = split_edge (FALLTHRU_EDGE (iter_part_bb));
  6161. body_bb = single_succ (seq_start_bb);
  6162. if (!broken_loop)
  6163. {
  6164. gcc_assert (BRANCH_EDGE (cont_bb)->dest == body_bb);
  6165. gcc_assert (EDGE_COUNT (cont_bb->succs) == 2);
  6166. trip_update_bb = split_edge (FALLTHRU_EDGE (cont_bb));
  6167. }
  6168. exit_bb = region->exit;
  6169. /* Trip and adjustment setup goes in ENTRY_BB. */
  6170. gsi = gsi_last_bb (entry_bb);
  6171. gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_FOR);
  6172. if (fd->collapse > 1)
  6173. {
  6174. int first_zero_iter = -1;
  6175. basic_block l2_dom_bb = NULL;
  6176. counts = XALLOCAVEC (tree, fd->collapse);
  6177. expand_omp_for_init_counts (fd, &gsi, entry_bb, counts,
  6178. fin_bb, first_zero_iter,
  6179. l2_dom_bb);
  6180. t = NULL_TREE;
  6181. }
  6182. else if (gimple_omp_for_combined_into_p (fd->for_stmt))
  6183. t = integer_one_node;
  6184. else
  6185. t = fold_binary (fd->loop.cond_code, boolean_type_node,
  6186. fold_convert (type, fd->loop.n1),
  6187. fold_convert (type, fd->loop.n2));
  6188. if (fd->collapse == 1
  6189. && TYPE_UNSIGNED (type)
  6190. && (t == NULL_TREE || !integer_onep (t)))
  6191. {
  6192. n1 = fold_convert (type, unshare_expr (fd->loop.n1));
  6193. n1 = force_gimple_operand_gsi (&gsi, n1, true, NULL_TREE,
  6194. true, GSI_SAME_STMT);
  6195. n2 = fold_convert (type, unshare_expr (fd->loop.n2));
  6196. n2 = force_gimple_operand_gsi (&gsi, n2, true, NULL_TREE,
  6197. true, GSI_SAME_STMT);
  6198. gcond *cond_stmt = gimple_build_cond (fd->loop.cond_code, n1, n2,
  6199. NULL_TREE, NULL_TREE);
  6200. gsi_insert_before (&gsi, cond_stmt, GSI_SAME_STMT);
  6201. if (walk_tree (gimple_cond_lhs_ptr (cond_stmt),
  6202. expand_omp_regimplify_p, NULL, NULL)
  6203. || walk_tree (gimple_cond_rhs_ptr (cond_stmt),
  6204. expand_omp_regimplify_p, NULL, NULL))
  6205. {
  6206. gsi = gsi_for_stmt (cond_stmt);
  6207. gimple_regimplify_operands (cond_stmt, &gsi);
  6208. }
  6209. se = split_block (entry_bb, cond_stmt);
  6210. se->flags = EDGE_TRUE_VALUE;
  6211. entry_bb = se->dest;
  6212. se->probability = REG_BR_PROB_BASE - (REG_BR_PROB_BASE / 2000 - 1);
  6213. se = make_edge (se->src, fin_bb, EDGE_FALSE_VALUE);
  6214. se->probability = REG_BR_PROB_BASE / 2000 - 1;
  6215. if (gimple_in_ssa_p (cfun))
  6216. {
  6217. int dest_idx = find_edge (entry_bb, fin_bb)->dest_idx;
  6218. for (gphi_iterator gpi = gsi_start_phis (fin_bb);
  6219. !gsi_end_p (gpi); gsi_next (&gpi))
  6220. {
  6221. gphi *phi = gpi.phi ();
  6222. add_phi_arg (phi, gimple_phi_arg_def (phi, dest_idx),
  6223. se, UNKNOWN_LOCATION);
  6224. }
  6225. }
  6226. gsi = gsi_last_bb (entry_bb);
  6227. }
  6228. switch (gimple_omp_for_kind (fd->for_stmt))
  6229. {
  6230. case GF_OMP_FOR_KIND_FOR:
  6231. nthreads = builtin_decl_explicit (BUILT_IN_OMP_GET_NUM_THREADS);
  6232. threadid = builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM);
  6233. break;
  6234. case GF_OMP_FOR_KIND_DISTRIBUTE:
  6235. nthreads = builtin_decl_explicit (BUILT_IN_OMP_GET_NUM_TEAMS);
  6236. threadid = builtin_decl_explicit (BUILT_IN_OMP_GET_TEAM_NUM);
  6237. break;
  6238. case GF_OMP_FOR_KIND_OACC_LOOP:
  6239. nthreads = builtin_decl_explicit (BUILT_IN_GOACC_GET_NUM_THREADS);
  6240. threadid = builtin_decl_explicit (BUILT_IN_GOACC_GET_THREAD_NUM);
  6241. break;
  6242. default:
  6243. gcc_unreachable ();
  6244. }
  6245. nthreads = build_call_expr (nthreads, 0);
  6246. nthreads = fold_convert (itype, nthreads);
  6247. nthreads = force_gimple_operand_gsi (&gsi, nthreads, true, NULL_TREE,
  6248. true, GSI_SAME_STMT);
  6249. threadid = build_call_expr (threadid, 0);
  6250. threadid = fold_convert (itype, threadid);
  6251. threadid = force_gimple_operand_gsi (&gsi, threadid, true, NULL_TREE,
  6252. true, GSI_SAME_STMT);
  6253. n1 = fd->loop.n1;
  6254. n2 = fd->loop.n2;
  6255. step = fd->loop.step;
  6256. if (gimple_omp_for_combined_into_p (fd->for_stmt))
  6257. {
  6258. tree innerc = find_omp_clause (gimple_omp_for_clauses (fd->for_stmt),
  6259. OMP_CLAUSE__LOOPTEMP_);
  6260. gcc_assert (innerc);
  6261. n1 = OMP_CLAUSE_DECL (innerc);
  6262. innerc = find_omp_clause (OMP_CLAUSE_CHAIN (innerc),
  6263. OMP_CLAUSE__LOOPTEMP_);
  6264. gcc_assert (innerc);
  6265. n2 = OMP_CLAUSE_DECL (innerc);
  6266. }
  6267. n1 = force_gimple_operand_gsi (&gsi, fold_convert (type, n1),
  6268. true, NULL_TREE, true, GSI_SAME_STMT);
  6269. n2 = force_gimple_operand_gsi (&gsi, fold_convert (itype, n2),
  6270. true, NULL_TREE, true, GSI_SAME_STMT);
  6271. step = force_gimple_operand_gsi (&gsi, fold_convert (itype, step),
  6272. true, NULL_TREE, true, GSI_SAME_STMT);
  6273. fd->chunk_size
  6274. = force_gimple_operand_gsi (&gsi, fold_convert (itype, fd->chunk_size),
  6275. true, NULL_TREE, true, GSI_SAME_STMT);
  6276. t = build_int_cst (itype, (fd->loop.cond_code == LT_EXPR ? -1 : 1));
  6277. t = fold_build2 (PLUS_EXPR, itype, step, t);
  6278. t = fold_build2 (PLUS_EXPR, itype, t, n2);
  6279. t = fold_build2 (MINUS_EXPR, itype, t, fold_convert (itype, n1));
  6280. if (TYPE_UNSIGNED (itype) && fd->loop.cond_code == GT_EXPR)
  6281. t = fold_build2 (TRUNC_DIV_EXPR, itype,
  6282. fold_build1 (NEGATE_EXPR, itype, t),
  6283. fold_build1 (NEGATE_EXPR, itype, step));
  6284. else
  6285. t = fold_build2 (TRUNC_DIV_EXPR, itype, t, step);
  6286. t = fold_convert (itype, t);
  6287. n = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
  6288. true, GSI_SAME_STMT);
  6289. trip_var = create_tmp_reg (itype, ".trip");
  6290. if (gimple_in_ssa_p (cfun))
  6291. {
  6292. trip_init = make_ssa_name (trip_var);
  6293. trip_main = make_ssa_name (trip_var);
  6294. trip_back = make_ssa_name (trip_var);
  6295. }
  6296. else
  6297. {
  6298. trip_init = trip_var;
  6299. trip_main = trip_var;
  6300. trip_back = trip_var;
  6301. }
  6302. gassign *assign_stmt
  6303. = gimple_build_assign (trip_init, build_int_cst (itype, 0));
  6304. gsi_insert_before (&gsi, assign_stmt, GSI_SAME_STMT);
  6305. t = fold_build2 (MULT_EXPR, itype, threadid, fd->chunk_size);
  6306. t = fold_build2 (MULT_EXPR, itype, t, step);
  6307. if (POINTER_TYPE_P (type))
  6308. t = fold_build_pointer_plus (n1, t);
  6309. else
  6310. t = fold_build2 (PLUS_EXPR, type, t, n1);
  6311. vextra = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
  6312. true, GSI_SAME_STMT);
  6313. /* Remove the GIMPLE_OMP_FOR. */
  6314. gsi_remove (&gsi, true);
  6315. /* Iteration space partitioning goes in ITER_PART_BB. */
  6316. gsi = gsi_last_bb (iter_part_bb);
  6317. t = fold_build2 (MULT_EXPR, itype, trip_main, nthreads);
  6318. t = fold_build2 (PLUS_EXPR, itype, t, threadid);
  6319. t = fold_build2 (MULT_EXPR, itype, t, fd->chunk_size);
  6320. s0 = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
  6321. false, GSI_CONTINUE_LINKING);
  6322. t = fold_build2 (PLUS_EXPR, itype, s0, fd->chunk_size);
  6323. t = fold_build2 (MIN_EXPR, itype, t, n);
  6324. e0 = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
  6325. false, GSI_CONTINUE_LINKING);
  6326. t = build2 (LT_EXPR, boolean_type_node, s0, n);
  6327. gsi_insert_after (&gsi, gimple_build_cond_empty (t), GSI_CONTINUE_LINKING);
  6328. /* Setup code for sequential iteration goes in SEQ_START_BB. */
  6329. gsi = gsi_start_bb (seq_start_bb);
  6330. tree startvar = fd->loop.v;
  6331. tree endvar = NULL_TREE;
  6332. if (gimple_omp_for_combined_p (fd->for_stmt))
  6333. {
  6334. tree clauses = gimple_code (inner_stmt) == GIMPLE_OMP_PARALLEL
  6335. ? gimple_omp_parallel_clauses (inner_stmt)
  6336. : gimple_omp_for_clauses (inner_stmt);
  6337. tree innerc = find_omp_clause (clauses, OMP_CLAUSE__LOOPTEMP_);
  6338. gcc_assert (innerc);
  6339. startvar = OMP_CLAUSE_DECL (innerc);
  6340. innerc = find_omp_clause (OMP_CLAUSE_CHAIN (innerc),
  6341. OMP_CLAUSE__LOOPTEMP_);
  6342. gcc_assert (innerc);
  6343. endvar = OMP_CLAUSE_DECL (innerc);
  6344. }
  6345. t = fold_convert (itype, s0);
  6346. t = fold_build2 (MULT_EXPR, itype, t, step);
  6347. if (POINTER_TYPE_P (type))
  6348. t = fold_build_pointer_plus (n1, t);
  6349. else
  6350. t = fold_build2 (PLUS_EXPR, type, t, n1);
  6351. t = fold_convert (TREE_TYPE (startvar), t);
  6352. t = force_gimple_operand_gsi (&gsi, t,
  6353. DECL_P (startvar)
  6354. && TREE_ADDRESSABLE (startvar),
  6355. NULL_TREE, false, GSI_CONTINUE_LINKING);
  6356. assign_stmt = gimple_build_assign (startvar, t);
  6357. gsi_insert_after (&gsi, assign_stmt, GSI_CONTINUE_LINKING);
  6358. t = fold_convert (itype, e0);
  6359. t = fold_build2 (MULT_EXPR, itype, t, step);
  6360. if (POINTER_TYPE_P (type))
  6361. t = fold_build_pointer_plus (n1, t);
  6362. else
  6363. t = fold_build2 (PLUS_EXPR, type, t, n1);
  6364. t = fold_convert (TREE_TYPE (startvar), t);
  6365. e = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
  6366. false, GSI_CONTINUE_LINKING);
  6367. if (endvar)
  6368. {
  6369. assign_stmt = gimple_build_assign (endvar, e);
  6370. gsi_insert_after (&gsi, assign_stmt, GSI_CONTINUE_LINKING);
  6371. if (useless_type_conversion_p (TREE_TYPE (fd->loop.v), TREE_TYPE (e)))
  6372. assign_stmt = gimple_build_assign (fd->loop.v, e);
  6373. else
  6374. assign_stmt = gimple_build_assign (fd->loop.v, NOP_EXPR, e);
  6375. gsi_insert_after (&gsi, assign_stmt, GSI_CONTINUE_LINKING);
  6376. }
  6377. if (fd->collapse > 1)
  6378. expand_omp_for_init_vars (fd, &gsi, counts, inner_stmt, startvar);
  6379. if (!broken_loop)
  6380. {
  6381. /* The code controlling the sequential loop goes in CONT_BB,
  6382. replacing the GIMPLE_OMP_CONTINUE. */
  6383. gsi = gsi_last_bb (cont_bb);
  6384. gomp_continue *cont_stmt = as_a <gomp_continue *> (gsi_stmt (gsi));
  6385. vmain = gimple_omp_continue_control_use (cont_stmt);
  6386. vback = gimple_omp_continue_control_def (cont_stmt);
  6387. if (!gimple_omp_for_combined_p (fd->for_stmt))
  6388. {
  6389. if (POINTER_TYPE_P (type))
  6390. t = fold_build_pointer_plus (vmain, step);
  6391. else
  6392. t = fold_build2 (PLUS_EXPR, type, vmain, step);
  6393. if (DECL_P (vback) && TREE_ADDRESSABLE (vback))
  6394. t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
  6395. true, GSI_SAME_STMT);
  6396. assign_stmt = gimple_build_assign (vback, t);
  6397. gsi_insert_before (&gsi, assign_stmt, GSI_SAME_STMT);
  6398. t = build2 (fd->loop.cond_code, boolean_type_node,
  6399. DECL_P (vback) && TREE_ADDRESSABLE (vback)
  6400. ? t : vback, e);
  6401. gsi_insert_before (&gsi, gimple_build_cond_empty (t), GSI_SAME_STMT);
  6402. }
  6403. /* Remove GIMPLE_OMP_CONTINUE. */
  6404. gsi_remove (&gsi, true);
  6405. if (fd->collapse > 1 && !gimple_omp_for_combined_p (fd->for_stmt))
  6406. collapse_bb = extract_omp_for_update_vars (fd, cont_bb, body_bb);
  6407. /* Trip update code goes into TRIP_UPDATE_BB. */
  6408. gsi = gsi_start_bb (trip_update_bb);
  6409. t = build_int_cst (itype, 1);
  6410. t = build2 (PLUS_EXPR, itype, trip_main, t);
  6411. assign_stmt = gimple_build_assign (trip_back, t);
  6412. gsi_insert_after (&gsi, assign_stmt, GSI_CONTINUE_LINKING);
  6413. }
  6414. /* Replace the GIMPLE_OMP_RETURN with a barrier, or nothing. */
  6415. gsi = gsi_last_bb (exit_bb);
  6416. if (!gimple_omp_return_nowait_p (gsi_stmt (gsi)))
  6417. {
  6418. t = gimple_omp_return_lhs (gsi_stmt (gsi));
  6419. if (gimple_omp_for_kind (fd->for_stmt) == GF_OMP_FOR_KIND_OACC_LOOP)
  6420. gcc_checking_assert (t == NULL_TREE);
  6421. else
  6422. gsi_insert_after (&gsi, build_omp_barrier (t), GSI_SAME_STMT);
  6423. }
  6424. gsi_remove (&gsi, true);
  6425. /* Connect the new blocks. */
  6426. find_edge (iter_part_bb, seq_start_bb)->flags = EDGE_TRUE_VALUE;
  6427. find_edge (iter_part_bb, fin_bb)->flags = EDGE_FALSE_VALUE;
  6428. if (!broken_loop)
  6429. {
  6430. se = find_edge (cont_bb, body_bb);
  6431. if (gimple_omp_for_combined_p (fd->for_stmt))
  6432. {
  6433. remove_edge (se);
  6434. se = NULL;
  6435. }
  6436. else if (fd->collapse > 1)
  6437. {
  6438. remove_edge (se);
  6439. se = make_edge (cont_bb, collapse_bb, EDGE_TRUE_VALUE);
  6440. }
  6441. else
  6442. se->flags = EDGE_TRUE_VALUE;
  6443. find_edge (cont_bb, trip_update_bb)->flags
  6444. = se ? EDGE_FALSE_VALUE : EDGE_FALLTHRU;
  6445. redirect_edge_and_branch (single_succ_edge (trip_update_bb), iter_part_bb);
  6446. }
  6447. if (gimple_in_ssa_p (cfun))
  6448. {
  6449. gphi_iterator psi;
  6450. gphi *phi;
  6451. edge re, ene;
  6452. edge_var_map *vm;
  6453. size_t i;
  6454. gcc_assert (fd->collapse == 1 && !broken_loop);
  6455. /* When we redirect the edge from trip_update_bb to iter_part_bb, we
  6456. remove arguments of the phi nodes in fin_bb. We need to create
  6457. appropriate phi nodes in iter_part_bb instead. */
  6458. se = single_pred_edge (fin_bb);
  6459. re = single_succ_edge (trip_update_bb);
  6460. vec<edge_var_map> *head = redirect_edge_var_map_vector (re);
  6461. ene = single_succ_edge (entry_bb);
  6462. psi = gsi_start_phis (fin_bb);
  6463. for (i = 0; !gsi_end_p (psi) && head->iterate (i, &vm);
  6464. gsi_next (&psi), ++i)
  6465. {
  6466. gphi *nphi;
  6467. source_location locus;
  6468. phi = psi.phi ();
  6469. t = gimple_phi_result (phi);
  6470. gcc_assert (t == redirect_edge_var_map_result (vm));
  6471. nphi = create_phi_node (t, iter_part_bb);
  6472. t = PHI_ARG_DEF_FROM_EDGE (phi, se);
  6473. locus = gimple_phi_arg_location_from_edge (phi, se);
  6474. /* A special case -- fd->loop.v is not yet computed in
  6475. iter_part_bb, we need to use vextra instead. */
  6476. if (t == fd->loop.v)
  6477. t = vextra;
  6478. add_phi_arg (nphi, t, ene, locus);
  6479. locus = redirect_edge_var_map_location (vm);
  6480. add_phi_arg (nphi, redirect_edge_var_map_def (vm), re, locus);
  6481. }
  6482. gcc_assert (gsi_end_p (psi) && i == head->length ());
  6483. redirect_edge_var_map_clear (re);
  6484. while (1)
  6485. {
  6486. psi = gsi_start_phis (fin_bb);
  6487. if (gsi_end_p (psi))
  6488. break;
  6489. remove_phi_node (&psi, false);
  6490. }
  6491. /* Make phi node for trip. */
  6492. phi = create_phi_node (trip_main, iter_part_bb);
  6493. add_phi_arg (phi, trip_back, single_succ_edge (trip_update_bb),
  6494. UNKNOWN_LOCATION);
  6495. add_phi_arg (phi, trip_init, single_succ_edge (entry_bb),
  6496. UNKNOWN_LOCATION);
  6497. }
  6498. if (!broken_loop)
  6499. set_immediate_dominator (CDI_DOMINATORS, trip_update_bb, cont_bb);
  6500. set_immediate_dominator (CDI_DOMINATORS, iter_part_bb,
  6501. recompute_dominator (CDI_DOMINATORS, iter_part_bb));
  6502. set_immediate_dominator (CDI_DOMINATORS, fin_bb,
  6503. recompute_dominator (CDI_DOMINATORS, fin_bb));
  6504. set_immediate_dominator (CDI_DOMINATORS, seq_start_bb,
  6505. recompute_dominator (CDI_DOMINATORS, seq_start_bb));
  6506. set_immediate_dominator (CDI_DOMINATORS, body_bb,
  6507. recompute_dominator (CDI_DOMINATORS, body_bb));
  6508. if (!broken_loop)
  6509. {
  6510. struct loop *trip_loop = alloc_loop ();
  6511. trip_loop->header = iter_part_bb;
  6512. trip_loop->latch = trip_update_bb;
  6513. add_loop (trip_loop, iter_part_bb->loop_father);
  6514. if (!gimple_omp_for_combined_p (fd->for_stmt))
  6515. {
  6516. struct loop *loop = alloc_loop ();
  6517. loop->header = body_bb;
  6518. if (collapse_bb == NULL)
  6519. loop->latch = cont_bb;
  6520. add_loop (loop, trip_loop);
  6521. }
  6522. }
  6523. }
  6524. /* A subroutine of expand_omp_for. Generate code for _Cilk_for loop.
  6525. Given parameters:
  6526. for (V = N1; V cond N2; V += STEP) BODY;
  6527. where COND is "<" or ">" or "!=", we generate pseudocode
  6528. for (ind_var = low; ind_var < high; ind_var++)
  6529. {
  6530. V = n1 + (ind_var * STEP)
  6531. <BODY>
  6532. }
  6533. In the above pseudocode, low and high are function parameters of the
  6534. child function. In the function below, we are inserting a temp.
  6535. variable that will be making a call to two OMP functions that will not be
  6536. found in the body of _Cilk_for (since OMP_FOR cannot be mixed
  6537. with _Cilk_for). These functions are replaced with low and high
  6538. by the function that handles taskreg. */
  6539. static void
  6540. expand_cilk_for (struct omp_region *region, struct omp_for_data *fd)
  6541. {
  6542. bool broken_loop = region->cont == NULL;
  6543. basic_block entry_bb = region->entry;
  6544. basic_block cont_bb = region->cont;
  6545. gcc_assert (EDGE_COUNT (entry_bb->succs) == 2);
  6546. gcc_assert (broken_loop
  6547. || BRANCH_EDGE (entry_bb)->dest == FALLTHRU_EDGE (cont_bb)->dest);
  6548. basic_block l0_bb = FALLTHRU_EDGE (entry_bb)->dest;
  6549. basic_block l1_bb, l2_bb;
  6550. if (!broken_loop)
  6551. {
  6552. gcc_assert (BRANCH_EDGE (cont_bb)->dest == l0_bb);
  6553. gcc_assert (EDGE_COUNT (cont_bb->succs) == 2);
  6554. l1_bb = split_block (cont_bb, last_stmt (cont_bb))->dest;
  6555. l2_bb = BRANCH_EDGE (entry_bb)->dest;
  6556. }
  6557. else
  6558. {
  6559. BRANCH_EDGE (entry_bb)->flags &= ~EDGE_ABNORMAL;
  6560. l1_bb = split_edge (BRANCH_EDGE (entry_bb));
  6561. l2_bb = single_succ (l1_bb);
  6562. }
  6563. basic_block exit_bb = region->exit;
  6564. basic_block l2_dom_bb = NULL;
  6565. gimple_stmt_iterator gsi = gsi_last_bb (entry_bb);
  6566. /* Below statements until the "tree high_val = ..." are pseudo statements
  6567. used to pass information to be used by expand_omp_taskreg.
  6568. low_val and high_val will be replaced by the __low and __high
  6569. parameter from the child function.
  6570. The call_exprs part is a place-holder, it is mainly used
  6571. to distinctly identify to the top-level part that this is
  6572. where we should put low and high (reasoning given in header
  6573. comment). */
  6574. tree child_fndecl
  6575. = gimple_omp_parallel_child_fn (
  6576. as_a <gomp_parallel *> (last_stmt (region->outer->entry)));
  6577. tree t, low_val = NULL_TREE, high_val = NULL_TREE;
  6578. for (t = DECL_ARGUMENTS (child_fndecl); t; t = TREE_CHAIN (t))
  6579. {
  6580. if (!strcmp (IDENTIFIER_POINTER (DECL_NAME (t)), "__high"))
  6581. high_val = t;
  6582. else if (!strcmp (IDENTIFIER_POINTER (DECL_NAME (t)), "__low"))
  6583. low_val = t;
  6584. }
  6585. gcc_assert (low_val && high_val);
  6586. tree type = TREE_TYPE (low_val);
  6587. tree ind_var = create_tmp_reg (type, "__cilk_ind_var");
  6588. gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_FOR);
  6589. /* Not needed in SSA form right now. */
  6590. gcc_assert (!gimple_in_ssa_p (cfun));
  6591. if (l2_dom_bb == NULL)
  6592. l2_dom_bb = l1_bb;
  6593. tree n1 = low_val;
  6594. tree n2 = high_val;
  6595. gimple stmt = gimple_build_assign (ind_var, n1);
  6596. /* Replace the GIMPLE_OMP_FOR statement. */
  6597. gsi_replace (&gsi, stmt, true);
  6598. if (!broken_loop)
  6599. {
  6600. /* Code to control the increment goes in the CONT_BB. */
  6601. gsi = gsi_last_bb (cont_bb);
  6602. stmt = gsi_stmt (gsi);
  6603. gcc_assert (gimple_code (stmt) == GIMPLE_OMP_CONTINUE);
  6604. stmt = gimple_build_assign (ind_var, PLUS_EXPR, ind_var,
  6605. build_one_cst (type));
  6606. /* Replace GIMPLE_OMP_CONTINUE. */
  6607. gsi_replace (&gsi, stmt, true);
  6608. }
  6609. /* Emit the condition in L1_BB. */
  6610. gsi = gsi_after_labels (l1_bb);
  6611. t = fold_build2 (MULT_EXPR, TREE_TYPE (fd->loop.step),
  6612. fold_convert (TREE_TYPE (fd->loop.step), ind_var),
  6613. fd->loop.step);
  6614. if (POINTER_TYPE_P (TREE_TYPE (fd->loop.n1)))
  6615. t = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (fd->loop.n1),
  6616. fd->loop.n1, fold_convert (sizetype, t));
  6617. else
  6618. t = fold_build2 (PLUS_EXPR, TREE_TYPE (fd->loop.n1),
  6619. fd->loop.n1, fold_convert (TREE_TYPE (fd->loop.n1), t));
  6620. t = fold_convert (TREE_TYPE (fd->loop.v), t);
  6621. expand_omp_build_assign (&gsi, fd->loop.v, t);
  6622. /* The condition is always '<' since the runtime will fill in the low
  6623. and high values. */
  6624. stmt = gimple_build_cond (LT_EXPR, ind_var, n2, NULL_TREE, NULL_TREE);
  6625. gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
  6626. /* Remove GIMPLE_OMP_RETURN. */
  6627. gsi = gsi_last_bb (exit_bb);
  6628. gsi_remove (&gsi, true);
  6629. /* Connect the new blocks. */
  6630. remove_edge (FALLTHRU_EDGE (entry_bb));
  6631. edge e, ne;
  6632. if (!broken_loop)
  6633. {
  6634. remove_edge (BRANCH_EDGE (entry_bb));
  6635. make_edge (entry_bb, l1_bb, EDGE_FALLTHRU);
  6636. e = BRANCH_EDGE (l1_bb);
  6637. ne = FALLTHRU_EDGE (l1_bb);
  6638. e->flags = EDGE_TRUE_VALUE;
  6639. }
  6640. else
  6641. {
  6642. single_succ_edge (entry_bb)->flags = EDGE_FALLTHRU;
  6643. ne = single_succ_edge (l1_bb);
  6644. e = make_edge (l1_bb, l0_bb, EDGE_TRUE_VALUE);
  6645. }
  6646. ne->flags = EDGE_FALSE_VALUE;
  6647. e->probability = REG_BR_PROB_BASE * 7 / 8;
  6648. ne->probability = REG_BR_PROB_BASE / 8;
  6649. set_immediate_dominator (CDI_DOMINATORS, l1_bb, entry_bb);
  6650. set_immediate_dominator (CDI_DOMINATORS, l2_bb, l2_dom_bb);
  6651. set_immediate_dominator (CDI_DOMINATORS, l0_bb, l1_bb);
  6652. if (!broken_loop)
  6653. {
  6654. struct loop *loop = alloc_loop ();
  6655. loop->header = l1_bb;
  6656. loop->latch = cont_bb;
  6657. add_loop (loop, l1_bb->loop_father);
  6658. loop->safelen = INT_MAX;
  6659. }
  6660. /* Pick the correct library function based on the precision of the
  6661. induction variable type. */
  6662. tree lib_fun = NULL_TREE;
  6663. if (TYPE_PRECISION (type) == 32)
  6664. lib_fun = cilk_for_32_fndecl;
  6665. else if (TYPE_PRECISION (type) == 64)
  6666. lib_fun = cilk_for_64_fndecl;
  6667. else
  6668. gcc_unreachable ();
  6669. gcc_assert (fd->sched_kind == OMP_CLAUSE_SCHEDULE_CILKFOR);
  6670. /* WS_ARGS contains the library function flavor to call:
  6671. __libcilkrts_cilk_for_64 or __libcilkrts_cilk_for_32), and the
  6672. user-defined grain value. If the user does not define one, then zero
  6673. is passed in by the parser. */
  6674. vec_alloc (region->ws_args, 2);
  6675. region->ws_args->quick_push (lib_fun);
  6676. region->ws_args->quick_push (fd->chunk_size);
  6677. }
  6678. /* A subroutine of expand_omp_for. Generate code for a simd non-worksharing
  6679. loop. Given parameters:
  6680. for (V = N1; V cond N2; V += STEP) BODY;
  6681. where COND is "<" or ">", we generate pseudocode
  6682. V = N1;
  6683. goto L1;
  6684. L0:
  6685. BODY;
  6686. V += STEP;
  6687. L1:
  6688. if (V cond N2) goto L0; else goto L2;
  6689. L2:
  6690. For collapsed loops, given parameters:
  6691. collapse(3)
  6692. for (V1 = N11; V1 cond1 N12; V1 += STEP1)
  6693. for (V2 = N21; V2 cond2 N22; V2 += STEP2)
  6694. for (V3 = N31; V3 cond3 N32; V3 += STEP3)
  6695. BODY;
  6696. we generate pseudocode
  6697. if (cond3 is <)
  6698. adj = STEP3 - 1;
  6699. else
  6700. adj = STEP3 + 1;
  6701. count3 = (adj + N32 - N31) / STEP3;
  6702. if (cond2 is <)
  6703. adj = STEP2 - 1;
  6704. else
  6705. adj = STEP2 + 1;
  6706. count2 = (adj + N22 - N21) / STEP2;
  6707. if (cond1 is <)
  6708. adj = STEP1 - 1;
  6709. else
  6710. adj = STEP1 + 1;
  6711. count1 = (adj + N12 - N11) / STEP1;
  6712. count = count1 * count2 * count3;
  6713. V = 0;
  6714. V1 = N11;
  6715. V2 = N21;
  6716. V3 = N31;
  6717. goto L1;
  6718. L0:
  6719. BODY;
  6720. V += 1;
  6721. V3 += STEP3;
  6722. V2 += (V3 cond3 N32) ? 0 : STEP2;
  6723. V3 = (V3 cond3 N32) ? V3 : N31;
  6724. V1 += (V2 cond2 N22) ? 0 : STEP1;
  6725. V2 = (V2 cond2 N22) ? V2 : N21;
  6726. L1:
  6727. if (V < count) goto L0; else goto L2;
  6728. L2:
  6729. */
  6730. static void
  6731. expand_omp_simd (struct omp_region *region, struct omp_for_data *fd)
  6732. {
  6733. tree type, t;
  6734. basic_block entry_bb, cont_bb, exit_bb, l0_bb, l1_bb, l2_bb, l2_dom_bb;
  6735. gimple_stmt_iterator gsi;
  6736. gimple stmt;
  6737. gcond *cond_stmt;
  6738. bool broken_loop = region->cont == NULL;
  6739. edge e, ne;
  6740. tree *counts = NULL;
  6741. int i;
  6742. tree safelen = find_omp_clause (gimple_omp_for_clauses (fd->for_stmt),
  6743. OMP_CLAUSE_SAFELEN);
  6744. tree simduid = find_omp_clause (gimple_omp_for_clauses (fd->for_stmt),
  6745. OMP_CLAUSE__SIMDUID_);
  6746. tree n1, n2;
  6747. type = TREE_TYPE (fd->loop.v);
  6748. entry_bb = region->entry;
  6749. cont_bb = region->cont;
  6750. gcc_assert (EDGE_COUNT (entry_bb->succs) == 2);
  6751. gcc_assert (broken_loop
  6752. || BRANCH_EDGE (entry_bb)->dest == FALLTHRU_EDGE (cont_bb)->dest);
  6753. l0_bb = FALLTHRU_EDGE (entry_bb)->dest;
  6754. if (!broken_loop)
  6755. {
  6756. gcc_assert (BRANCH_EDGE (cont_bb)->dest == l0_bb);
  6757. gcc_assert (EDGE_COUNT (cont_bb->succs) == 2);
  6758. l1_bb = split_block (cont_bb, last_stmt (cont_bb))->dest;
  6759. l2_bb = BRANCH_EDGE (entry_bb)->dest;
  6760. }
  6761. else
  6762. {
  6763. BRANCH_EDGE (entry_bb)->flags &= ~EDGE_ABNORMAL;
  6764. l1_bb = split_edge (BRANCH_EDGE (entry_bb));
  6765. l2_bb = single_succ (l1_bb);
  6766. }
  6767. exit_bb = region->exit;
  6768. l2_dom_bb = NULL;
  6769. gsi = gsi_last_bb (entry_bb);
  6770. gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_FOR);
  6771. /* Not needed in SSA form right now. */
  6772. gcc_assert (!gimple_in_ssa_p (cfun));
  6773. if (fd->collapse > 1)
  6774. {
  6775. int first_zero_iter = -1;
  6776. basic_block zero_iter_bb = l2_bb;
  6777. counts = XALLOCAVEC (tree, fd->collapse);
  6778. expand_omp_for_init_counts (fd, &gsi, entry_bb, counts,
  6779. zero_iter_bb, first_zero_iter,
  6780. l2_dom_bb);
  6781. }
  6782. if (l2_dom_bb == NULL)
  6783. l2_dom_bb = l1_bb;
  6784. n1 = fd->loop.n1;
  6785. n2 = fd->loop.n2;
  6786. if (gimple_omp_for_combined_into_p (fd->for_stmt))
  6787. {
  6788. tree innerc = find_omp_clause (gimple_omp_for_clauses (fd->for_stmt),
  6789. OMP_CLAUSE__LOOPTEMP_);
  6790. gcc_assert (innerc);
  6791. n1 = OMP_CLAUSE_DECL (innerc);
  6792. innerc = find_omp_clause (OMP_CLAUSE_CHAIN (innerc),
  6793. OMP_CLAUSE__LOOPTEMP_);
  6794. gcc_assert (innerc);
  6795. n2 = OMP_CLAUSE_DECL (innerc);
  6796. expand_omp_build_assign (&gsi, fd->loop.v,
  6797. fold_convert (type, n1));
  6798. if (fd->collapse > 1)
  6799. {
  6800. gsi_prev (&gsi);
  6801. expand_omp_for_init_vars (fd, &gsi, counts, NULL, n1);
  6802. gsi_next (&gsi);
  6803. }
  6804. }
  6805. else
  6806. {
  6807. expand_omp_build_assign (&gsi, fd->loop.v,
  6808. fold_convert (type, fd->loop.n1));
  6809. if (fd->collapse > 1)
  6810. for (i = 0; i < fd->collapse; i++)
  6811. {
  6812. tree itype = TREE_TYPE (fd->loops[i].v);
  6813. if (POINTER_TYPE_P (itype))
  6814. itype = signed_type_for (itype);
  6815. t = fold_convert (TREE_TYPE (fd->loops[i].v), fd->loops[i].n1);
  6816. expand_omp_build_assign (&gsi, fd->loops[i].v, t);
  6817. }
  6818. }
  6819. /* Remove the GIMPLE_OMP_FOR statement. */
  6820. gsi_remove (&gsi, true);
  6821. if (!broken_loop)
  6822. {
  6823. /* Code to control the increment goes in the CONT_BB. */
  6824. gsi = gsi_last_bb (cont_bb);
  6825. stmt = gsi_stmt (gsi);
  6826. gcc_assert (gimple_code (stmt) == GIMPLE_OMP_CONTINUE);
  6827. if (POINTER_TYPE_P (type))
  6828. t = fold_build_pointer_plus (fd->loop.v, fd->loop.step);
  6829. else
  6830. t = fold_build2 (PLUS_EXPR, type, fd->loop.v, fd->loop.step);
  6831. expand_omp_build_assign (&gsi, fd->loop.v, t);
  6832. if (fd->collapse > 1)
  6833. {
  6834. i = fd->collapse - 1;
  6835. if (POINTER_TYPE_P (TREE_TYPE (fd->loops[i].v)))
  6836. {
  6837. t = fold_convert (sizetype, fd->loops[i].step);
  6838. t = fold_build_pointer_plus (fd->loops[i].v, t);
  6839. }
  6840. else
  6841. {
  6842. t = fold_convert (TREE_TYPE (fd->loops[i].v),
  6843. fd->loops[i].step);
  6844. t = fold_build2 (PLUS_EXPR, TREE_TYPE (fd->loops[i].v),
  6845. fd->loops[i].v, t);
  6846. }
  6847. expand_omp_build_assign (&gsi, fd->loops[i].v, t);
  6848. for (i = fd->collapse - 1; i > 0; i--)
  6849. {
  6850. tree itype = TREE_TYPE (fd->loops[i].v);
  6851. tree itype2 = TREE_TYPE (fd->loops[i - 1].v);
  6852. if (POINTER_TYPE_P (itype2))
  6853. itype2 = signed_type_for (itype2);
  6854. t = build3 (COND_EXPR, itype2,
  6855. build2 (fd->loops[i].cond_code, boolean_type_node,
  6856. fd->loops[i].v,
  6857. fold_convert (itype, fd->loops[i].n2)),
  6858. build_int_cst (itype2, 0),
  6859. fold_convert (itype2, fd->loops[i - 1].step));
  6860. if (POINTER_TYPE_P (TREE_TYPE (fd->loops[i - 1].v)))
  6861. t = fold_build_pointer_plus (fd->loops[i - 1].v, t);
  6862. else
  6863. t = fold_build2 (PLUS_EXPR, itype2, fd->loops[i - 1].v, t);
  6864. expand_omp_build_assign (&gsi, fd->loops[i - 1].v, t);
  6865. t = build3 (COND_EXPR, itype,
  6866. build2 (fd->loops[i].cond_code, boolean_type_node,
  6867. fd->loops[i].v,
  6868. fold_convert (itype, fd->loops[i].n2)),
  6869. fd->loops[i].v,
  6870. fold_convert (itype, fd->loops[i].n1));
  6871. expand_omp_build_assign (&gsi, fd->loops[i].v, t);
  6872. }
  6873. }
  6874. /* Remove GIMPLE_OMP_CONTINUE. */
  6875. gsi_remove (&gsi, true);
  6876. }
  6877. /* Emit the condition in L1_BB. */
  6878. gsi = gsi_start_bb (l1_bb);
  6879. t = fold_convert (type, n2);
  6880. t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
  6881. false, GSI_CONTINUE_LINKING);
  6882. t = build2 (fd->loop.cond_code, boolean_type_node, fd->loop.v, t);
  6883. cond_stmt = gimple_build_cond_empty (t);
  6884. gsi_insert_after (&gsi, cond_stmt, GSI_CONTINUE_LINKING);
  6885. if (walk_tree (gimple_cond_lhs_ptr (cond_stmt), expand_omp_regimplify_p,
  6886. NULL, NULL)
  6887. || walk_tree (gimple_cond_rhs_ptr (cond_stmt), expand_omp_regimplify_p,
  6888. NULL, NULL))
  6889. {
  6890. gsi = gsi_for_stmt (cond_stmt);
  6891. gimple_regimplify_operands (cond_stmt, &gsi);
  6892. }
  6893. /* Remove GIMPLE_OMP_RETURN. */
  6894. gsi = gsi_last_bb (exit_bb);
  6895. gsi_remove (&gsi, true);
  6896. /* Connect the new blocks. */
  6897. remove_edge (FALLTHRU_EDGE (entry_bb));
  6898. if (!broken_loop)
  6899. {
  6900. remove_edge (BRANCH_EDGE (entry_bb));
  6901. make_edge (entry_bb, l1_bb, EDGE_FALLTHRU);
  6902. e = BRANCH_EDGE (l1_bb);
  6903. ne = FALLTHRU_EDGE (l1_bb);
  6904. e->flags = EDGE_TRUE_VALUE;
  6905. }
  6906. else
  6907. {
  6908. single_succ_edge (entry_bb)->flags = EDGE_FALLTHRU;
  6909. ne = single_succ_edge (l1_bb);
  6910. e = make_edge (l1_bb, l0_bb, EDGE_TRUE_VALUE);
  6911. }
  6912. ne->flags = EDGE_FALSE_VALUE;
  6913. e->probability = REG_BR_PROB_BASE * 7 / 8;
  6914. ne->probability = REG_BR_PROB_BASE / 8;
  6915. set_immediate_dominator (CDI_DOMINATORS, l1_bb, entry_bb);
  6916. set_immediate_dominator (CDI_DOMINATORS, l2_bb, l2_dom_bb);
  6917. set_immediate_dominator (CDI_DOMINATORS, l0_bb, l1_bb);
  6918. if (!broken_loop)
  6919. {
  6920. struct loop *loop = alloc_loop ();
  6921. loop->header = l1_bb;
  6922. loop->latch = cont_bb;
  6923. add_loop (loop, l1_bb->loop_father);
  6924. if (safelen == NULL_TREE)
  6925. loop->safelen = INT_MAX;
  6926. else
  6927. {
  6928. safelen = OMP_CLAUSE_SAFELEN_EXPR (safelen);
  6929. if (TREE_CODE (safelen) != INTEGER_CST)
  6930. loop->safelen = 0;
  6931. else if (!tree_fits_uhwi_p (safelen)
  6932. || tree_to_uhwi (safelen) > INT_MAX)
  6933. loop->safelen = INT_MAX;
  6934. else
  6935. loop->safelen = tree_to_uhwi (safelen);
  6936. if (loop->safelen == 1)
  6937. loop->safelen = 0;
  6938. }
  6939. if (simduid)
  6940. {
  6941. loop->simduid = OMP_CLAUSE__SIMDUID__DECL (simduid);
  6942. cfun->has_simduid_loops = true;
  6943. }
  6944. /* If not -fno-tree-loop-vectorize, hint that we want to vectorize
  6945. the loop. */
  6946. if ((flag_tree_loop_vectorize
  6947. || (!global_options_set.x_flag_tree_loop_vectorize
  6948. && !global_options_set.x_flag_tree_vectorize))
  6949. && flag_tree_loop_optimize
  6950. && loop->safelen > 1)
  6951. {
  6952. loop->force_vectorize = true;
  6953. cfun->has_force_vectorize_loops = true;
  6954. }
  6955. }
  6956. else if (simduid)
  6957. cfun->has_simduid_loops = true;
  6958. }
  6959. /* Expand the OMP loop defined by REGION. */
  6960. static void
  6961. expand_omp_for (struct omp_region *region, gimple inner_stmt)
  6962. {
  6963. struct omp_for_data fd;
  6964. struct omp_for_data_loop *loops;
  6965. loops
  6966. = (struct omp_for_data_loop *)
  6967. alloca (gimple_omp_for_collapse (last_stmt (region->entry))
  6968. * sizeof (struct omp_for_data_loop));
  6969. extract_omp_for_data (as_a <gomp_for *> (last_stmt (region->entry)),
  6970. &fd, loops);
  6971. region->sched_kind = fd.sched_kind;
  6972. gcc_assert (EDGE_COUNT (region->entry->succs) == 2);
  6973. BRANCH_EDGE (region->entry)->flags &= ~EDGE_ABNORMAL;
  6974. FALLTHRU_EDGE (region->entry)->flags &= ~EDGE_ABNORMAL;
  6975. if (region->cont)
  6976. {
  6977. gcc_assert (EDGE_COUNT (region->cont->succs) == 2);
  6978. BRANCH_EDGE (region->cont)->flags &= ~EDGE_ABNORMAL;
  6979. FALLTHRU_EDGE (region->cont)->flags &= ~EDGE_ABNORMAL;
  6980. }
  6981. else
  6982. /* If there isn't a continue then this is a degerate case where
  6983. the introduction of abnormal edges during lowering will prevent
  6984. original loops from being detected. Fix that up. */
  6985. loops_state_set (LOOPS_NEED_FIXUP);
  6986. if (gimple_omp_for_kind (fd.for_stmt) & GF_OMP_FOR_SIMD)
  6987. expand_omp_simd (region, &fd);
  6988. else if (gimple_omp_for_kind (fd.for_stmt) == GF_OMP_FOR_KIND_CILKFOR)
  6989. expand_cilk_for (region, &fd);
  6990. else if (fd.sched_kind == OMP_CLAUSE_SCHEDULE_STATIC
  6991. && !fd.have_ordered)
  6992. {
  6993. if (fd.chunk_size == NULL)
  6994. expand_omp_for_static_nochunk (region, &fd, inner_stmt);
  6995. else
  6996. expand_omp_for_static_chunk (region, &fd, inner_stmt);
  6997. }
  6998. else
  6999. {
  7000. int fn_index, start_ix, next_ix;
  7001. gcc_assert (gimple_omp_for_kind (fd.for_stmt)
  7002. == GF_OMP_FOR_KIND_FOR);
  7003. if (fd.chunk_size == NULL
  7004. && fd.sched_kind == OMP_CLAUSE_SCHEDULE_STATIC)
  7005. fd.chunk_size = integer_zero_node;
  7006. gcc_assert (fd.sched_kind != OMP_CLAUSE_SCHEDULE_AUTO);
  7007. fn_index = (fd.sched_kind == OMP_CLAUSE_SCHEDULE_RUNTIME)
  7008. ? 3 : fd.sched_kind;
  7009. fn_index += fd.have_ordered * 4;
  7010. start_ix = ((int)BUILT_IN_GOMP_LOOP_STATIC_START) + fn_index;
  7011. next_ix = ((int)BUILT_IN_GOMP_LOOP_STATIC_NEXT) + fn_index;
  7012. if (fd.iter_type == long_long_unsigned_type_node)
  7013. {
  7014. start_ix += ((int)BUILT_IN_GOMP_LOOP_ULL_STATIC_START
  7015. - (int)BUILT_IN_GOMP_LOOP_STATIC_START);
  7016. next_ix += ((int)BUILT_IN_GOMP_LOOP_ULL_STATIC_NEXT
  7017. - (int)BUILT_IN_GOMP_LOOP_STATIC_NEXT);
  7018. }
  7019. expand_omp_for_generic (region, &fd, (enum built_in_function) start_ix,
  7020. (enum built_in_function) next_ix, inner_stmt);
  7021. }
  7022. if (gimple_in_ssa_p (cfun))
  7023. update_ssa (TODO_update_ssa_only_virtuals);
  7024. }
  7025. /* Expand code for an OpenMP sections directive. In pseudo code, we generate
  7026. v = GOMP_sections_start (n);
  7027. L0:
  7028. switch (v)
  7029. {
  7030. case 0:
  7031. goto L2;
  7032. case 1:
  7033. section 1;
  7034. goto L1;
  7035. case 2:
  7036. ...
  7037. case n:
  7038. ...
  7039. default:
  7040. abort ();
  7041. }
  7042. L1:
  7043. v = GOMP_sections_next ();
  7044. goto L0;
  7045. L2:
  7046. reduction;
  7047. If this is a combined parallel sections, replace the call to
  7048. GOMP_sections_start with call to GOMP_sections_next. */
  7049. static void
  7050. expand_omp_sections (struct omp_region *region)
  7051. {
  7052. tree t, u, vin = NULL, vmain, vnext, l2;
  7053. unsigned len;
  7054. basic_block entry_bb, l0_bb, l1_bb, l2_bb, default_bb;
  7055. gimple_stmt_iterator si, switch_si;
  7056. gomp_sections *sections_stmt;
  7057. gimple stmt;
  7058. gomp_continue *cont;
  7059. edge_iterator ei;
  7060. edge e;
  7061. struct omp_region *inner;
  7062. unsigned i, casei;
  7063. bool exit_reachable = region->cont != NULL;
  7064. gcc_assert (region->exit != NULL);
  7065. entry_bb = region->entry;
  7066. l0_bb = single_succ (entry_bb);
  7067. l1_bb = region->cont;
  7068. l2_bb = region->exit;
  7069. if (single_pred_p (l2_bb) && single_pred (l2_bb) == l0_bb)
  7070. l2 = gimple_block_label (l2_bb);
  7071. else
  7072. {
  7073. /* This can happen if there are reductions. */
  7074. len = EDGE_COUNT (l0_bb->succs);
  7075. gcc_assert (len > 0);
  7076. e = EDGE_SUCC (l0_bb, len - 1);
  7077. si = gsi_last_bb (e->dest);
  7078. l2 = NULL_TREE;
  7079. if (gsi_end_p (si)
  7080. || gimple_code (gsi_stmt (si)) != GIMPLE_OMP_SECTION)
  7081. l2 = gimple_block_label (e->dest);
  7082. else
  7083. FOR_EACH_EDGE (e, ei, l0_bb->succs)
  7084. {
  7085. si = gsi_last_bb (e->dest);
  7086. if (gsi_end_p (si)
  7087. || gimple_code (gsi_stmt (si)) != GIMPLE_OMP_SECTION)
  7088. {
  7089. l2 = gimple_block_label (e->dest);
  7090. break;
  7091. }
  7092. }
  7093. }
  7094. if (exit_reachable)
  7095. default_bb = create_empty_bb (l1_bb->prev_bb);
  7096. else
  7097. default_bb = create_empty_bb (l0_bb);
  7098. /* We will build a switch() with enough cases for all the
  7099. GIMPLE_OMP_SECTION regions, a '0' case to handle the end of more work
  7100. and a default case to abort if something goes wrong. */
  7101. len = EDGE_COUNT (l0_bb->succs);
  7102. /* Use vec::quick_push on label_vec throughout, since we know the size
  7103. in advance. */
  7104. auto_vec<tree> label_vec (len);
  7105. /* The call to GOMP_sections_start goes in ENTRY_BB, replacing the
  7106. GIMPLE_OMP_SECTIONS statement. */
  7107. si = gsi_last_bb (entry_bb);
  7108. sections_stmt = as_a <gomp_sections *> (gsi_stmt (si));
  7109. gcc_assert (gimple_code (sections_stmt) == GIMPLE_OMP_SECTIONS);
  7110. vin = gimple_omp_sections_control (sections_stmt);
  7111. if (!is_combined_parallel (region))
  7112. {
  7113. /* If we are not inside a combined parallel+sections region,
  7114. call GOMP_sections_start. */
  7115. t = build_int_cst (unsigned_type_node, len - 1);
  7116. u = builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_START);
  7117. stmt = gimple_build_call (u, 1, t);
  7118. }
  7119. else
  7120. {
  7121. /* Otherwise, call GOMP_sections_next. */
  7122. u = builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_NEXT);
  7123. stmt = gimple_build_call (u, 0);
  7124. }
  7125. gimple_call_set_lhs (stmt, vin);
  7126. gsi_insert_after (&si, stmt, GSI_SAME_STMT);
  7127. gsi_remove (&si, true);
  7128. /* The switch() statement replacing GIMPLE_OMP_SECTIONS_SWITCH goes in
  7129. L0_BB. */
  7130. switch_si = gsi_last_bb (l0_bb);
  7131. gcc_assert (gimple_code (gsi_stmt (switch_si)) == GIMPLE_OMP_SECTIONS_SWITCH);
  7132. if (exit_reachable)
  7133. {
  7134. cont = as_a <gomp_continue *> (last_stmt (l1_bb));
  7135. gcc_assert (gimple_code (cont) == GIMPLE_OMP_CONTINUE);
  7136. vmain = gimple_omp_continue_control_use (cont);
  7137. vnext = gimple_omp_continue_control_def (cont);
  7138. }
  7139. else
  7140. {
  7141. vmain = vin;
  7142. vnext = NULL_TREE;
  7143. }
  7144. t = build_case_label (build_int_cst (unsigned_type_node, 0), NULL, l2);
  7145. label_vec.quick_push (t);
  7146. i = 1;
  7147. /* Convert each GIMPLE_OMP_SECTION into a CASE_LABEL_EXPR. */
  7148. for (inner = region->inner, casei = 1;
  7149. inner;
  7150. inner = inner->next, i++, casei++)
  7151. {
  7152. basic_block s_entry_bb, s_exit_bb;
  7153. /* Skip optional reduction region. */
  7154. if (inner->type == GIMPLE_OMP_ATOMIC_LOAD)
  7155. {
  7156. --i;
  7157. --casei;
  7158. continue;
  7159. }
  7160. s_entry_bb = inner->entry;
  7161. s_exit_bb = inner->exit;
  7162. t = gimple_block_label (s_entry_bb);
  7163. u = build_int_cst (unsigned_type_node, casei);
  7164. u = build_case_label (u, NULL, t);
  7165. label_vec.quick_push (u);
  7166. si = gsi_last_bb (s_entry_bb);
  7167. gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_SECTION);
  7168. gcc_assert (i < len || gimple_omp_section_last_p (gsi_stmt (si)));
  7169. gsi_remove (&si, true);
  7170. single_succ_edge (s_entry_bb)->flags = EDGE_FALLTHRU;
  7171. if (s_exit_bb == NULL)
  7172. continue;
  7173. si = gsi_last_bb (s_exit_bb);
  7174. gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_RETURN);
  7175. gsi_remove (&si, true);
  7176. single_succ_edge (s_exit_bb)->flags = EDGE_FALLTHRU;
  7177. }
  7178. /* Error handling code goes in DEFAULT_BB. */
  7179. t = gimple_block_label (default_bb);
  7180. u = build_case_label (NULL, NULL, t);
  7181. make_edge (l0_bb, default_bb, 0);
  7182. add_bb_to_loop (default_bb, current_loops->tree_root);
  7183. stmt = gimple_build_switch (vmain, u, label_vec);
  7184. gsi_insert_after (&switch_si, stmt, GSI_SAME_STMT);
  7185. gsi_remove (&switch_si, true);
  7186. si = gsi_start_bb (default_bb);
  7187. stmt = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
  7188. gsi_insert_after (&si, stmt, GSI_CONTINUE_LINKING);
  7189. if (exit_reachable)
  7190. {
  7191. tree bfn_decl;
  7192. /* Code to get the next section goes in L1_BB. */
  7193. si = gsi_last_bb (l1_bb);
  7194. gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_CONTINUE);
  7195. bfn_decl = builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_NEXT);
  7196. stmt = gimple_build_call (bfn_decl, 0);
  7197. gimple_call_set_lhs (stmt, vnext);
  7198. gsi_insert_after (&si, stmt, GSI_SAME_STMT);
  7199. gsi_remove (&si, true);
  7200. single_succ_edge (l1_bb)->flags = EDGE_FALLTHRU;
  7201. }
  7202. /* Cleanup function replaces GIMPLE_OMP_RETURN in EXIT_BB. */
  7203. si = gsi_last_bb (l2_bb);
  7204. if (gimple_omp_return_nowait_p (gsi_stmt (si)))
  7205. t = builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_END_NOWAIT);
  7206. else if (gimple_omp_return_lhs (gsi_stmt (si)))
  7207. t = builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_END_CANCEL);
  7208. else
  7209. t = builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_END);
  7210. stmt = gimple_build_call (t, 0);
  7211. if (gimple_omp_return_lhs (gsi_stmt (si)))
  7212. gimple_call_set_lhs (stmt, gimple_omp_return_lhs (gsi_stmt (si)));
  7213. gsi_insert_after (&si, stmt, GSI_SAME_STMT);
  7214. gsi_remove (&si, true);
  7215. set_immediate_dominator (CDI_DOMINATORS, default_bb, l0_bb);
  7216. }
  7217. /* Expand code for an OpenMP single directive. We've already expanded
  7218. much of the code, here we simply place the GOMP_barrier call. */
  7219. static void
  7220. expand_omp_single (struct omp_region *region)
  7221. {
  7222. basic_block entry_bb, exit_bb;
  7223. gimple_stmt_iterator si;
  7224. entry_bb = region->entry;
  7225. exit_bb = region->exit;
  7226. si = gsi_last_bb (entry_bb);
  7227. gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_SINGLE);
  7228. gsi_remove (&si, true);
  7229. single_succ_edge (entry_bb)->flags = EDGE_FALLTHRU;
  7230. si = gsi_last_bb (exit_bb);
  7231. if (!gimple_omp_return_nowait_p (gsi_stmt (si)))
  7232. {
  7233. tree t = gimple_omp_return_lhs (gsi_stmt (si));
  7234. gsi_insert_after (&si, build_omp_barrier (t), GSI_SAME_STMT);
  7235. }
  7236. gsi_remove (&si, true);
  7237. single_succ_edge (exit_bb)->flags = EDGE_FALLTHRU;
  7238. }
  7239. /* Generic expansion for OpenMP synchronization directives: master,
  7240. ordered and critical. All we need to do here is remove the entry
  7241. and exit markers for REGION. */
  7242. static void
  7243. expand_omp_synch (struct omp_region *region)
  7244. {
  7245. basic_block entry_bb, exit_bb;
  7246. gimple_stmt_iterator si;
  7247. entry_bb = region->entry;
  7248. exit_bb = region->exit;
  7249. si = gsi_last_bb (entry_bb);
  7250. gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_SINGLE
  7251. || gimple_code (gsi_stmt (si)) == GIMPLE_OMP_MASTER
  7252. || gimple_code (gsi_stmt (si)) == GIMPLE_OMP_TASKGROUP
  7253. || gimple_code (gsi_stmt (si)) == GIMPLE_OMP_ORDERED
  7254. || gimple_code (gsi_stmt (si)) == GIMPLE_OMP_CRITICAL
  7255. || gimple_code (gsi_stmt (si)) == GIMPLE_OMP_TEAMS);
  7256. gsi_remove (&si, true);
  7257. single_succ_edge (entry_bb)->flags = EDGE_FALLTHRU;
  7258. if (exit_bb)
  7259. {
  7260. si = gsi_last_bb (exit_bb);
  7261. gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_RETURN);
  7262. gsi_remove (&si, true);
  7263. single_succ_edge (exit_bb)->flags = EDGE_FALLTHRU;
  7264. }
  7265. }
  7266. /* A subroutine of expand_omp_atomic. Attempt to implement the atomic
  7267. operation as a normal volatile load. */
  7268. static bool
  7269. expand_omp_atomic_load (basic_block load_bb, tree addr,
  7270. tree loaded_val, int index)
  7271. {
  7272. enum built_in_function tmpbase;
  7273. gimple_stmt_iterator gsi;
  7274. basic_block store_bb;
  7275. location_t loc;
  7276. gimple stmt;
  7277. tree decl, call, type, itype;
  7278. gsi = gsi_last_bb (load_bb);
  7279. stmt = gsi_stmt (gsi);
  7280. gcc_assert (gimple_code (stmt) == GIMPLE_OMP_ATOMIC_LOAD);
  7281. loc = gimple_location (stmt);
  7282. /* ??? If the target does not implement atomic_load_optab[mode], and mode
  7283. is smaller than word size, then expand_atomic_load assumes that the load
  7284. is atomic. We could avoid the builtin entirely in this case. */
  7285. tmpbase = (enum built_in_function) (BUILT_IN_ATOMIC_LOAD_N + index + 1);
  7286. decl = builtin_decl_explicit (tmpbase);
  7287. if (decl == NULL_TREE)
  7288. return false;
  7289. type = TREE_TYPE (loaded_val);
  7290. itype = TREE_TYPE (TREE_TYPE (decl));
  7291. call = build_call_expr_loc (loc, decl, 2, addr,
  7292. build_int_cst (NULL,
  7293. gimple_omp_atomic_seq_cst_p (stmt)
  7294. ? MEMMODEL_SEQ_CST
  7295. : MEMMODEL_RELAXED));
  7296. if (!useless_type_conversion_p (type, itype))
  7297. call = fold_build1_loc (loc, VIEW_CONVERT_EXPR, type, call);
  7298. call = build2_loc (loc, MODIFY_EXPR, void_type_node, loaded_val, call);
  7299. force_gimple_operand_gsi (&gsi, call, true, NULL_TREE, true, GSI_SAME_STMT);
  7300. gsi_remove (&gsi, true);
  7301. store_bb = single_succ (load_bb);
  7302. gsi = gsi_last_bb (store_bb);
  7303. gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_ATOMIC_STORE);
  7304. gsi_remove (&gsi, true);
  7305. if (gimple_in_ssa_p (cfun))
  7306. update_ssa (TODO_update_ssa_no_phi);
  7307. return true;
  7308. }
  7309. /* A subroutine of expand_omp_atomic. Attempt to implement the atomic
  7310. operation as a normal volatile store. */
  7311. static bool
  7312. expand_omp_atomic_store (basic_block load_bb, tree addr,
  7313. tree loaded_val, tree stored_val, int index)
  7314. {
  7315. enum built_in_function tmpbase;
  7316. gimple_stmt_iterator gsi;
  7317. basic_block store_bb = single_succ (load_bb);
  7318. location_t loc;
  7319. gimple stmt;
  7320. tree decl, call, type, itype;
  7321. machine_mode imode;
  7322. bool exchange;
  7323. gsi = gsi_last_bb (load_bb);
  7324. stmt = gsi_stmt (gsi);
  7325. gcc_assert (gimple_code (stmt) == GIMPLE_OMP_ATOMIC_LOAD);
  7326. /* If the load value is needed, then this isn't a store but an exchange. */
  7327. exchange = gimple_omp_atomic_need_value_p (stmt);
  7328. gsi = gsi_last_bb (store_bb);
  7329. stmt = gsi_stmt (gsi);
  7330. gcc_assert (gimple_code (stmt) == GIMPLE_OMP_ATOMIC_STORE);
  7331. loc = gimple_location (stmt);
  7332. /* ??? If the target does not implement atomic_store_optab[mode], and mode
  7333. is smaller than word size, then expand_atomic_store assumes that the store
  7334. is atomic. We could avoid the builtin entirely in this case. */
  7335. tmpbase = (exchange ? BUILT_IN_ATOMIC_EXCHANGE_N : BUILT_IN_ATOMIC_STORE_N);
  7336. tmpbase = (enum built_in_function) ((int) tmpbase + index + 1);
  7337. decl = builtin_decl_explicit (tmpbase);
  7338. if (decl == NULL_TREE)
  7339. return false;
  7340. type = TREE_TYPE (stored_val);
  7341. /* Dig out the type of the function's second argument. */
  7342. itype = TREE_TYPE (decl);
  7343. itype = TYPE_ARG_TYPES (itype);
  7344. itype = TREE_CHAIN (itype);
  7345. itype = TREE_VALUE (itype);
  7346. imode = TYPE_MODE (itype);
  7347. if (exchange && !can_atomic_exchange_p (imode, true))
  7348. return false;
  7349. if (!useless_type_conversion_p (itype, type))
  7350. stored_val = fold_build1_loc (loc, VIEW_CONVERT_EXPR, itype, stored_val);
  7351. call = build_call_expr_loc (loc, decl, 3, addr, stored_val,
  7352. build_int_cst (NULL,
  7353. gimple_omp_atomic_seq_cst_p (stmt)
  7354. ? MEMMODEL_SEQ_CST
  7355. : MEMMODEL_RELAXED));
  7356. if (exchange)
  7357. {
  7358. if (!useless_type_conversion_p (type, itype))
  7359. call = build1_loc (loc, VIEW_CONVERT_EXPR, type, call);
  7360. call = build2_loc (loc, MODIFY_EXPR, void_type_node, loaded_val, call);
  7361. }
  7362. force_gimple_operand_gsi (&gsi, call, true, NULL_TREE, true, GSI_SAME_STMT);
  7363. gsi_remove (&gsi, true);
  7364. /* Remove the GIMPLE_OMP_ATOMIC_LOAD that we verified above. */
  7365. gsi = gsi_last_bb (load_bb);
  7366. gsi_remove (&gsi, true);
  7367. if (gimple_in_ssa_p (cfun))
  7368. update_ssa (TODO_update_ssa_no_phi);
  7369. return true;
  7370. }
  7371. /* A subroutine of expand_omp_atomic. Attempt to implement the atomic
  7372. operation as a __atomic_fetch_op builtin. INDEX is log2 of the
  7373. size of the data type, and thus usable to find the index of the builtin
  7374. decl. Returns false if the expression is not of the proper form. */
  7375. static bool
  7376. expand_omp_atomic_fetch_op (basic_block load_bb,
  7377. tree addr, tree loaded_val,
  7378. tree stored_val, int index)
  7379. {
  7380. enum built_in_function oldbase, newbase, tmpbase;
  7381. tree decl, itype, call;
  7382. tree lhs, rhs;
  7383. basic_block store_bb = single_succ (load_bb);
  7384. gimple_stmt_iterator gsi;
  7385. gimple stmt;
  7386. location_t loc;
  7387. enum tree_code code;
  7388. bool need_old, need_new;
  7389. machine_mode imode;
  7390. bool seq_cst;
  7391. /* We expect to find the following sequences:
  7392. load_bb:
  7393. GIMPLE_OMP_ATOMIC_LOAD (tmp, mem)
  7394. store_bb:
  7395. val = tmp OP something; (or: something OP tmp)
  7396. GIMPLE_OMP_STORE (val)
  7397. ???FIXME: Allow a more flexible sequence.
  7398. Perhaps use data flow to pick the statements.
  7399. */
  7400. gsi = gsi_after_labels (store_bb);
  7401. stmt = gsi_stmt (gsi);
  7402. loc = gimple_location (stmt);
  7403. if (!is_gimple_assign (stmt))
  7404. return false;
  7405. gsi_next (&gsi);
  7406. if (gimple_code (gsi_stmt (gsi)) != GIMPLE_OMP_ATOMIC_STORE)
  7407. return false;
  7408. need_new = gimple_omp_atomic_need_value_p (gsi_stmt (gsi));
  7409. need_old = gimple_omp_atomic_need_value_p (last_stmt (load_bb));
  7410. seq_cst = gimple_omp_atomic_seq_cst_p (last_stmt (load_bb));
  7411. gcc_checking_assert (!need_old || !need_new);
  7412. if (!operand_equal_p (gimple_assign_lhs (stmt), stored_val, 0))
  7413. return false;
  7414. /* Check for one of the supported fetch-op operations. */
  7415. code = gimple_assign_rhs_code (stmt);
  7416. switch (code)
  7417. {
  7418. case PLUS_EXPR:
  7419. case POINTER_PLUS_EXPR:
  7420. oldbase = BUILT_IN_ATOMIC_FETCH_ADD_N;
  7421. newbase = BUILT_IN_ATOMIC_ADD_FETCH_N;
  7422. break;
  7423. case MINUS_EXPR:
  7424. oldbase = BUILT_IN_ATOMIC_FETCH_SUB_N;
  7425. newbase = BUILT_IN_ATOMIC_SUB_FETCH_N;
  7426. break;
  7427. case BIT_AND_EXPR:
  7428. oldbase = BUILT_IN_ATOMIC_FETCH_AND_N;
  7429. newbase = BUILT_IN_ATOMIC_AND_FETCH_N;
  7430. break;
  7431. case BIT_IOR_EXPR:
  7432. oldbase = BUILT_IN_ATOMIC_FETCH_OR_N;
  7433. newbase = BUILT_IN_ATOMIC_OR_FETCH_N;
  7434. break;
  7435. case BIT_XOR_EXPR:
  7436. oldbase = BUILT_IN_ATOMIC_FETCH_XOR_N;
  7437. newbase = BUILT_IN_ATOMIC_XOR_FETCH_N;
  7438. break;
  7439. default:
  7440. return false;
  7441. }
  7442. /* Make sure the expression is of the proper form. */
  7443. if (operand_equal_p (gimple_assign_rhs1 (stmt), loaded_val, 0))
  7444. rhs = gimple_assign_rhs2 (stmt);
  7445. else if (commutative_tree_code (gimple_assign_rhs_code (stmt))
  7446. && operand_equal_p (gimple_assign_rhs2 (stmt), loaded_val, 0))
  7447. rhs = gimple_assign_rhs1 (stmt);
  7448. else
  7449. return false;
  7450. tmpbase = ((enum built_in_function)
  7451. ((need_new ? newbase : oldbase) + index + 1));
  7452. decl = builtin_decl_explicit (tmpbase);
  7453. if (decl == NULL_TREE)
  7454. return false;
  7455. itype = TREE_TYPE (TREE_TYPE (decl));
  7456. imode = TYPE_MODE (itype);
  7457. /* We could test all of the various optabs involved, but the fact of the
  7458. matter is that (with the exception of i486 vs i586 and xadd) all targets
  7459. that support any atomic operaton optab also implements compare-and-swap.
  7460. Let optabs.c take care of expanding any compare-and-swap loop. */
  7461. if (!can_compare_and_swap_p (imode, true))
  7462. return false;
  7463. gsi = gsi_last_bb (load_bb);
  7464. gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_ATOMIC_LOAD);
  7465. /* OpenMP does not imply any barrier-like semantics on its atomic ops.
  7466. It only requires that the operation happen atomically. Thus we can
  7467. use the RELAXED memory model. */
  7468. call = build_call_expr_loc (loc, decl, 3, addr,
  7469. fold_convert_loc (loc, itype, rhs),
  7470. build_int_cst (NULL,
  7471. seq_cst ? MEMMODEL_SEQ_CST
  7472. : MEMMODEL_RELAXED));
  7473. if (need_old || need_new)
  7474. {
  7475. lhs = need_old ? loaded_val : stored_val;
  7476. call = fold_convert_loc (loc, TREE_TYPE (lhs), call);
  7477. call = build2_loc (loc, MODIFY_EXPR, void_type_node, lhs, call);
  7478. }
  7479. else
  7480. call = fold_convert_loc (loc, void_type_node, call);
  7481. force_gimple_operand_gsi (&gsi, call, true, NULL_TREE, true, GSI_SAME_STMT);
  7482. gsi_remove (&gsi, true);
  7483. gsi = gsi_last_bb (store_bb);
  7484. gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_ATOMIC_STORE);
  7485. gsi_remove (&gsi, true);
  7486. gsi = gsi_last_bb (store_bb);
  7487. gsi_remove (&gsi, true);
  7488. if (gimple_in_ssa_p (cfun))
  7489. update_ssa (TODO_update_ssa_no_phi);
  7490. return true;
  7491. }
  7492. /* A subroutine of expand_omp_atomic. Implement the atomic operation as:
  7493. oldval = *addr;
  7494. repeat:
  7495. newval = rhs; // with oldval replacing *addr in rhs
  7496. oldval = __sync_val_compare_and_swap (addr, oldval, newval);
  7497. if (oldval != newval)
  7498. goto repeat;
  7499. INDEX is log2 of the size of the data type, and thus usable to find the
  7500. index of the builtin decl. */
  7501. static bool
  7502. expand_omp_atomic_pipeline (basic_block load_bb, basic_block store_bb,
  7503. tree addr, tree loaded_val, tree stored_val,
  7504. int index)
  7505. {
  7506. tree loadedi, storedi, initial, new_storedi, old_vali;
  7507. tree type, itype, cmpxchg, iaddr;
  7508. gimple_stmt_iterator si;
  7509. basic_block loop_header = single_succ (load_bb);
  7510. gimple phi, stmt;
  7511. edge e;
  7512. enum built_in_function fncode;
  7513. /* ??? We need a non-pointer interface to __atomic_compare_exchange in
  7514. order to use the RELAXED memory model effectively. */
  7515. fncode = (enum built_in_function)((int)BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_N
  7516. + index + 1);
  7517. cmpxchg = builtin_decl_explicit (fncode);
  7518. if (cmpxchg == NULL_TREE)
  7519. return false;
  7520. type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (addr)));
  7521. itype = TREE_TYPE (TREE_TYPE (cmpxchg));
  7522. if (!can_compare_and_swap_p (TYPE_MODE (itype), true))
  7523. return false;
  7524. /* Load the initial value, replacing the GIMPLE_OMP_ATOMIC_LOAD. */
  7525. si = gsi_last_bb (load_bb);
  7526. gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_ATOMIC_LOAD);
  7527. /* For floating-point values, we'll need to view-convert them to integers
  7528. so that we can perform the atomic compare and swap. Simplify the
  7529. following code by always setting up the "i"ntegral variables. */
  7530. if (!INTEGRAL_TYPE_P (type) && !POINTER_TYPE_P (type))
  7531. {
  7532. tree iaddr_val;
  7533. iaddr = create_tmp_reg (build_pointer_type_for_mode (itype, ptr_mode,
  7534. true));
  7535. iaddr_val
  7536. = force_gimple_operand_gsi (&si,
  7537. fold_convert (TREE_TYPE (iaddr), addr),
  7538. false, NULL_TREE, true, GSI_SAME_STMT);
  7539. stmt = gimple_build_assign (iaddr, iaddr_val);
  7540. gsi_insert_before (&si, stmt, GSI_SAME_STMT);
  7541. loadedi = create_tmp_var (itype);
  7542. if (gimple_in_ssa_p (cfun))
  7543. loadedi = make_ssa_name (loadedi);
  7544. }
  7545. else
  7546. {
  7547. iaddr = addr;
  7548. loadedi = loaded_val;
  7549. }
  7550. fncode = (enum built_in_function) (BUILT_IN_ATOMIC_LOAD_N + index + 1);
  7551. tree loaddecl = builtin_decl_explicit (fncode);
  7552. if (loaddecl)
  7553. initial
  7554. = fold_convert (TREE_TYPE (TREE_TYPE (iaddr)),
  7555. build_call_expr (loaddecl, 2, iaddr,
  7556. build_int_cst (NULL_TREE,
  7557. MEMMODEL_RELAXED)));
  7558. else
  7559. initial = build2 (MEM_REF, TREE_TYPE (TREE_TYPE (iaddr)), iaddr,
  7560. build_int_cst (TREE_TYPE (iaddr), 0));
  7561. initial
  7562. = force_gimple_operand_gsi (&si, initial, true, NULL_TREE, true,
  7563. GSI_SAME_STMT);
  7564. /* Move the value to the LOADEDI temporary. */
  7565. if (gimple_in_ssa_p (cfun))
  7566. {
  7567. gcc_assert (gimple_seq_empty_p (phi_nodes (loop_header)));
  7568. phi = create_phi_node (loadedi, loop_header);
  7569. SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (phi, single_succ_edge (load_bb)),
  7570. initial);
  7571. }
  7572. else
  7573. gsi_insert_before (&si,
  7574. gimple_build_assign (loadedi, initial),
  7575. GSI_SAME_STMT);
  7576. if (loadedi != loaded_val)
  7577. {
  7578. gimple_stmt_iterator gsi2;
  7579. tree x;
  7580. x = build1 (VIEW_CONVERT_EXPR, type, loadedi);
  7581. gsi2 = gsi_start_bb (loop_header);
  7582. if (gimple_in_ssa_p (cfun))
  7583. {
  7584. gassign *stmt;
  7585. x = force_gimple_operand_gsi (&gsi2, x, true, NULL_TREE,
  7586. true, GSI_SAME_STMT);
  7587. stmt = gimple_build_assign (loaded_val, x);
  7588. gsi_insert_before (&gsi2, stmt, GSI_SAME_STMT);
  7589. }
  7590. else
  7591. {
  7592. x = build2 (MODIFY_EXPR, TREE_TYPE (loaded_val), loaded_val, x);
  7593. force_gimple_operand_gsi (&gsi2, x, true, NULL_TREE,
  7594. true, GSI_SAME_STMT);
  7595. }
  7596. }
  7597. gsi_remove (&si, true);
  7598. si = gsi_last_bb (store_bb);
  7599. gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_ATOMIC_STORE);
  7600. if (iaddr == addr)
  7601. storedi = stored_val;
  7602. else
  7603. storedi =
  7604. force_gimple_operand_gsi (&si,
  7605. build1 (VIEW_CONVERT_EXPR, itype,
  7606. stored_val), true, NULL_TREE, true,
  7607. GSI_SAME_STMT);
  7608. /* Build the compare&swap statement. */
  7609. new_storedi = build_call_expr (cmpxchg, 3, iaddr, loadedi, storedi);
  7610. new_storedi = force_gimple_operand_gsi (&si,
  7611. fold_convert (TREE_TYPE (loadedi),
  7612. new_storedi),
  7613. true, NULL_TREE,
  7614. true, GSI_SAME_STMT);
  7615. if (gimple_in_ssa_p (cfun))
  7616. old_vali = loadedi;
  7617. else
  7618. {
  7619. old_vali = create_tmp_var (TREE_TYPE (loadedi));
  7620. stmt = gimple_build_assign (old_vali, loadedi);
  7621. gsi_insert_before (&si, stmt, GSI_SAME_STMT);
  7622. stmt = gimple_build_assign (loadedi, new_storedi);
  7623. gsi_insert_before (&si, stmt, GSI_SAME_STMT);
  7624. }
  7625. /* Note that we always perform the comparison as an integer, even for
  7626. floating point. This allows the atomic operation to properly
  7627. succeed even with NaNs and -0.0. */
  7628. stmt = gimple_build_cond_empty
  7629. (build2 (NE_EXPR, boolean_type_node,
  7630. new_storedi, old_vali));
  7631. gsi_insert_before (&si, stmt, GSI_SAME_STMT);
  7632. /* Update cfg. */
  7633. e = single_succ_edge (store_bb);
  7634. e->flags &= ~EDGE_FALLTHRU;
  7635. e->flags |= EDGE_FALSE_VALUE;
  7636. e = make_edge (store_bb, loop_header, EDGE_TRUE_VALUE);
  7637. /* Copy the new value to loadedi (we already did that before the condition
  7638. if we are not in SSA). */
  7639. if (gimple_in_ssa_p (cfun))
  7640. {
  7641. phi = gimple_seq_first_stmt (phi_nodes (loop_header));
  7642. SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (phi, e), new_storedi);
  7643. }
  7644. /* Remove GIMPLE_OMP_ATOMIC_STORE. */
  7645. gsi_remove (&si, true);
  7646. struct loop *loop = alloc_loop ();
  7647. loop->header = loop_header;
  7648. loop->latch = store_bb;
  7649. add_loop (loop, loop_header->loop_father);
  7650. if (gimple_in_ssa_p (cfun))
  7651. update_ssa (TODO_update_ssa_no_phi);
  7652. return true;
  7653. }
  7654. /* A subroutine of expand_omp_atomic. Implement the atomic operation as:
  7655. GOMP_atomic_start ();
  7656. *addr = rhs;
  7657. GOMP_atomic_end ();
  7658. The result is not globally atomic, but works so long as all parallel
  7659. references are within #pragma omp atomic directives. According to
  7660. responses received from omp@openmp.org, appears to be within spec.
  7661. Which makes sense, since that's how several other compilers handle
  7662. this situation as well.
  7663. LOADED_VAL and ADDR are the operands of GIMPLE_OMP_ATOMIC_LOAD we're
  7664. expanding. STORED_VAL is the operand of the matching
  7665. GIMPLE_OMP_ATOMIC_STORE.
  7666. We replace
  7667. GIMPLE_OMP_ATOMIC_LOAD (loaded_val, addr) with
  7668. loaded_val = *addr;
  7669. and replace
  7670. GIMPLE_OMP_ATOMIC_STORE (stored_val) with
  7671. *addr = stored_val;
  7672. */
  7673. static bool
  7674. expand_omp_atomic_mutex (basic_block load_bb, basic_block store_bb,
  7675. tree addr, tree loaded_val, tree stored_val)
  7676. {
  7677. gimple_stmt_iterator si;
  7678. gassign *stmt;
  7679. tree t;
  7680. si = gsi_last_bb (load_bb);
  7681. gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_ATOMIC_LOAD);
  7682. t = builtin_decl_explicit (BUILT_IN_GOMP_ATOMIC_START);
  7683. t = build_call_expr (t, 0);
  7684. force_gimple_operand_gsi (&si, t, true, NULL_TREE, true, GSI_SAME_STMT);
  7685. stmt = gimple_build_assign (loaded_val, build_simple_mem_ref (addr));
  7686. gsi_insert_before (&si, stmt, GSI_SAME_STMT);
  7687. gsi_remove (&si, true);
  7688. si = gsi_last_bb (store_bb);
  7689. gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_ATOMIC_STORE);
  7690. stmt = gimple_build_assign (build_simple_mem_ref (unshare_expr (addr)),
  7691. stored_val);
  7692. gsi_insert_before (&si, stmt, GSI_SAME_STMT);
  7693. t = builtin_decl_explicit (BUILT_IN_GOMP_ATOMIC_END);
  7694. t = build_call_expr (t, 0);
  7695. force_gimple_operand_gsi (&si, t, true, NULL_TREE, true, GSI_SAME_STMT);
  7696. gsi_remove (&si, true);
  7697. if (gimple_in_ssa_p (cfun))
  7698. update_ssa (TODO_update_ssa_no_phi);
  7699. return true;
  7700. }
  7701. /* Expand an GIMPLE_OMP_ATOMIC statement. We try to expand
  7702. using expand_omp_atomic_fetch_op. If it failed, we try to
  7703. call expand_omp_atomic_pipeline, and if it fails too, the
  7704. ultimate fallback is wrapping the operation in a mutex
  7705. (expand_omp_atomic_mutex). REGION is the atomic region built
  7706. by build_omp_regions_1(). */
  7707. static void
  7708. expand_omp_atomic (struct omp_region *region)
  7709. {
  7710. basic_block load_bb = region->entry, store_bb = region->exit;
  7711. gomp_atomic_load *load = as_a <gomp_atomic_load *> (last_stmt (load_bb));
  7712. gomp_atomic_store *store = as_a <gomp_atomic_store *> (last_stmt (store_bb));
  7713. tree loaded_val = gimple_omp_atomic_load_lhs (load);
  7714. tree addr = gimple_omp_atomic_load_rhs (load);
  7715. tree stored_val = gimple_omp_atomic_store_val (store);
  7716. tree type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (addr)));
  7717. HOST_WIDE_INT index;
  7718. /* Make sure the type is one of the supported sizes. */
  7719. index = tree_to_uhwi (TYPE_SIZE_UNIT (type));
  7720. index = exact_log2 (index);
  7721. if (index >= 0 && index <= 4)
  7722. {
  7723. unsigned int align = TYPE_ALIGN_UNIT (type);
  7724. /* __sync builtins require strict data alignment. */
  7725. if (exact_log2 (align) >= index)
  7726. {
  7727. /* Atomic load. */
  7728. if (loaded_val == stored_val
  7729. && (GET_MODE_CLASS (TYPE_MODE (type)) == MODE_INT
  7730. || GET_MODE_CLASS (TYPE_MODE (type)) == MODE_FLOAT)
  7731. && GET_MODE_BITSIZE (TYPE_MODE (type)) <= BITS_PER_WORD
  7732. && expand_omp_atomic_load (load_bb, addr, loaded_val, index))
  7733. return;
  7734. /* Atomic store. */
  7735. if ((GET_MODE_CLASS (TYPE_MODE (type)) == MODE_INT
  7736. || GET_MODE_CLASS (TYPE_MODE (type)) == MODE_FLOAT)
  7737. && GET_MODE_BITSIZE (TYPE_MODE (type)) <= BITS_PER_WORD
  7738. && store_bb == single_succ (load_bb)
  7739. && first_stmt (store_bb) == store
  7740. && expand_omp_atomic_store (load_bb, addr, loaded_val,
  7741. stored_val, index))
  7742. return;
  7743. /* When possible, use specialized atomic update functions. */
  7744. if ((INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type))
  7745. && store_bb == single_succ (load_bb)
  7746. && expand_omp_atomic_fetch_op (load_bb, addr,
  7747. loaded_val, stored_val, index))
  7748. return;
  7749. /* If we don't have specialized __sync builtins, try and implement
  7750. as a compare and swap loop. */
  7751. if (expand_omp_atomic_pipeline (load_bb, store_bb, addr,
  7752. loaded_val, stored_val, index))
  7753. return;
  7754. }
  7755. }
  7756. /* The ultimate fallback is wrapping the operation in a mutex. */
  7757. expand_omp_atomic_mutex (load_bb, store_bb, addr, loaded_val, stored_val);
  7758. }
  7759. /* Expand the GIMPLE_OMP_TARGET starting at REGION. */
  7760. static void
  7761. expand_omp_target (struct omp_region *region)
  7762. {
  7763. basic_block entry_bb, exit_bb, new_bb;
  7764. struct function *child_cfun;
  7765. tree child_fn, block, t;
  7766. gimple_stmt_iterator gsi;
  7767. gomp_target *entry_stmt;
  7768. gimple stmt;
  7769. edge e;
  7770. bool offloaded, data_region;
  7771. entry_stmt = as_a <gomp_target *> (last_stmt (region->entry));
  7772. new_bb = region->entry;
  7773. offloaded = is_gimple_omp_offloaded (entry_stmt);
  7774. switch (gimple_omp_target_kind (entry_stmt))
  7775. {
  7776. case GF_OMP_TARGET_KIND_REGION:
  7777. case GF_OMP_TARGET_KIND_UPDATE:
  7778. case GF_OMP_TARGET_KIND_OACC_PARALLEL:
  7779. case GF_OMP_TARGET_KIND_OACC_KERNELS:
  7780. case GF_OMP_TARGET_KIND_OACC_UPDATE:
  7781. case GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA:
  7782. data_region = false;
  7783. break;
  7784. case GF_OMP_TARGET_KIND_DATA:
  7785. case GF_OMP_TARGET_KIND_OACC_DATA:
  7786. data_region = true;
  7787. break;
  7788. default:
  7789. gcc_unreachable ();
  7790. }
  7791. child_fn = NULL_TREE;
  7792. child_cfun = NULL;
  7793. if (offloaded)
  7794. {
  7795. child_fn = gimple_omp_target_child_fn (entry_stmt);
  7796. child_cfun = DECL_STRUCT_FUNCTION (child_fn);
  7797. }
  7798. /* Supported by expand_omp_taskreg, but not here. */
  7799. if (child_cfun != NULL)
  7800. gcc_checking_assert (!child_cfun->cfg);
  7801. gcc_checking_assert (!gimple_in_ssa_p (cfun));
  7802. entry_bb = region->entry;
  7803. exit_bb = region->exit;
  7804. if (offloaded)
  7805. {
  7806. unsigned srcidx, dstidx, num;
  7807. /* If the offloading region needs data sent from the parent
  7808. function, then the very first statement (except possible
  7809. tree profile counter updates) of the offloading body
  7810. is a copy assignment .OMP_DATA_I = &.OMP_DATA_O. Since
  7811. &.OMP_DATA_O is passed as an argument to the child function,
  7812. we need to replace it with the argument as seen by the child
  7813. function.
  7814. In most cases, this will end up being the identity assignment
  7815. .OMP_DATA_I = .OMP_DATA_I. However, if the offloading body had
  7816. a function call that has been inlined, the original PARM_DECL
  7817. .OMP_DATA_I may have been converted into a different local
  7818. variable. In which case, we need to keep the assignment. */
  7819. tree data_arg = gimple_omp_target_data_arg (entry_stmt);
  7820. if (data_arg)
  7821. {
  7822. basic_block entry_succ_bb = single_succ (entry_bb);
  7823. gimple_stmt_iterator gsi;
  7824. tree arg;
  7825. gimple tgtcopy_stmt = NULL;
  7826. tree sender = TREE_VEC_ELT (data_arg, 0);
  7827. for (gsi = gsi_start_bb (entry_succ_bb); ; gsi_next (&gsi))
  7828. {
  7829. gcc_assert (!gsi_end_p (gsi));
  7830. stmt = gsi_stmt (gsi);
  7831. if (gimple_code (stmt) != GIMPLE_ASSIGN)
  7832. continue;
  7833. if (gimple_num_ops (stmt) == 2)
  7834. {
  7835. tree arg = gimple_assign_rhs1 (stmt);
  7836. /* We're ignoring the subcode because we're
  7837. effectively doing a STRIP_NOPS. */
  7838. if (TREE_CODE (arg) == ADDR_EXPR
  7839. && TREE_OPERAND (arg, 0) == sender)
  7840. {
  7841. tgtcopy_stmt = stmt;
  7842. break;
  7843. }
  7844. }
  7845. }
  7846. gcc_assert (tgtcopy_stmt != NULL);
  7847. arg = DECL_ARGUMENTS (child_fn);
  7848. gcc_assert (gimple_assign_lhs (tgtcopy_stmt) == arg);
  7849. gsi_remove (&gsi, true);
  7850. }
  7851. /* Declare local variables needed in CHILD_CFUN. */
  7852. block = DECL_INITIAL (child_fn);
  7853. BLOCK_VARS (block) = vec2chain (child_cfun->local_decls);
  7854. /* The gimplifier could record temporaries in the offloading block
  7855. rather than in containing function's local_decls chain,
  7856. which would mean cgraph missed finalizing them. Do it now. */
  7857. for (t = BLOCK_VARS (block); t; t = DECL_CHAIN (t))
  7858. if (TREE_CODE (t) == VAR_DECL
  7859. && TREE_STATIC (t)
  7860. && !DECL_EXTERNAL (t))
  7861. varpool_node::finalize_decl (t);
  7862. DECL_SAVED_TREE (child_fn) = NULL;
  7863. /* We'll create a CFG for child_fn, so no gimple body is needed. */
  7864. gimple_set_body (child_fn, NULL);
  7865. TREE_USED (block) = 1;
  7866. /* Reset DECL_CONTEXT on function arguments. */
  7867. for (t = DECL_ARGUMENTS (child_fn); t; t = DECL_CHAIN (t))
  7868. DECL_CONTEXT (t) = child_fn;
  7869. /* Split ENTRY_BB at GIMPLE_*,
  7870. so that it can be moved to the child function. */
  7871. gsi = gsi_last_bb (entry_bb);
  7872. stmt = gsi_stmt (gsi);
  7873. gcc_assert (stmt
  7874. && gimple_code (stmt) == gimple_code (entry_stmt));
  7875. e = split_block (entry_bb, stmt);
  7876. gsi_remove (&gsi, true);
  7877. entry_bb = e->dest;
  7878. single_succ_edge (entry_bb)->flags = EDGE_FALLTHRU;
  7879. /* Convert GIMPLE_OMP_RETURN into a RETURN_EXPR. */
  7880. if (exit_bb)
  7881. {
  7882. gsi = gsi_last_bb (exit_bb);
  7883. gcc_assert (!gsi_end_p (gsi)
  7884. && gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_RETURN);
  7885. stmt = gimple_build_return (NULL);
  7886. gsi_insert_after (&gsi, stmt, GSI_SAME_STMT);
  7887. gsi_remove (&gsi, true);
  7888. }
  7889. /* Move the offloading region into CHILD_CFUN. */
  7890. block = gimple_block (entry_stmt);
  7891. new_bb = move_sese_region_to_fn (child_cfun, entry_bb, exit_bb, block);
  7892. if (exit_bb)
  7893. single_succ_edge (new_bb)->flags = EDGE_FALLTHRU;
  7894. /* When the OMP expansion process cannot guarantee an up-to-date
  7895. loop tree arrange for the child function to fixup loops. */
  7896. if (loops_state_satisfies_p (LOOPS_NEED_FIXUP))
  7897. child_cfun->x_current_loops->state |= LOOPS_NEED_FIXUP;
  7898. /* Remove non-local VAR_DECLs from child_cfun->local_decls list. */
  7899. num = vec_safe_length (child_cfun->local_decls);
  7900. for (srcidx = 0, dstidx = 0; srcidx < num; srcidx++)
  7901. {
  7902. t = (*child_cfun->local_decls)[srcidx];
  7903. if (DECL_CONTEXT (t) == cfun->decl)
  7904. continue;
  7905. if (srcidx != dstidx)
  7906. (*child_cfun->local_decls)[dstidx] = t;
  7907. dstidx++;
  7908. }
  7909. if (dstidx != num)
  7910. vec_safe_truncate (child_cfun->local_decls, dstidx);
  7911. /* Inform the callgraph about the new function. */
  7912. child_cfun->curr_properties = cfun->curr_properties;
  7913. child_cfun->has_simduid_loops |= cfun->has_simduid_loops;
  7914. child_cfun->has_force_vectorize_loops |= cfun->has_force_vectorize_loops;
  7915. cgraph_node::add_new_function (child_fn, true);
  7916. #ifdef ENABLE_OFFLOADING
  7917. /* Add the new function to the offload table. */
  7918. vec_safe_push (offload_funcs, child_fn);
  7919. #endif
  7920. /* Fix the callgraph edges for child_cfun. Those for cfun will be
  7921. fixed in a following pass. */
  7922. push_cfun (child_cfun);
  7923. cgraph_edge::rebuild_edges ();
  7924. #ifdef ENABLE_OFFLOADING
  7925. /* Prevent IPA from removing child_fn as unreachable, since there are no
  7926. refs from the parent function to child_fn in offload LTO mode. */
  7927. struct cgraph_node *node = cgraph_node::get (child_fn);
  7928. node->mark_force_output ();
  7929. #endif
  7930. /* Some EH regions might become dead, see PR34608. If
  7931. pass_cleanup_cfg isn't the first pass to happen with the
  7932. new child, these dead EH edges might cause problems.
  7933. Clean them up now. */
  7934. if (flag_exceptions)
  7935. {
  7936. basic_block bb;
  7937. bool changed = false;
  7938. FOR_EACH_BB_FN (bb, cfun)
  7939. changed |= gimple_purge_dead_eh_edges (bb);
  7940. if (changed)
  7941. cleanup_tree_cfg ();
  7942. }
  7943. pop_cfun ();
  7944. }
  7945. /* Emit a library call to launch the offloading region, or do data
  7946. transfers. */
  7947. tree t1, t2, t3, t4, device, cond, c, clauses;
  7948. enum built_in_function start_ix;
  7949. location_t clause_loc;
  7950. switch (gimple_omp_target_kind (entry_stmt))
  7951. {
  7952. case GF_OMP_TARGET_KIND_REGION:
  7953. start_ix = BUILT_IN_GOMP_TARGET;
  7954. break;
  7955. case GF_OMP_TARGET_KIND_DATA:
  7956. start_ix = BUILT_IN_GOMP_TARGET_DATA;
  7957. break;
  7958. case GF_OMP_TARGET_KIND_UPDATE:
  7959. start_ix = BUILT_IN_GOMP_TARGET_UPDATE;
  7960. break;
  7961. case GF_OMP_TARGET_KIND_OACC_PARALLEL:
  7962. case GF_OMP_TARGET_KIND_OACC_KERNELS:
  7963. start_ix = BUILT_IN_GOACC_PARALLEL;
  7964. break;
  7965. case GF_OMP_TARGET_KIND_OACC_DATA:
  7966. start_ix = BUILT_IN_GOACC_DATA_START;
  7967. break;
  7968. case GF_OMP_TARGET_KIND_OACC_UPDATE:
  7969. start_ix = BUILT_IN_GOACC_UPDATE;
  7970. break;
  7971. case GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA:
  7972. start_ix = BUILT_IN_GOACC_ENTER_EXIT_DATA;
  7973. break;
  7974. default:
  7975. gcc_unreachable ();
  7976. }
  7977. clauses = gimple_omp_target_clauses (entry_stmt);
  7978. /* By default, the value of DEVICE is GOMP_DEVICE_ICV (let runtime
  7979. library choose) and there is no conditional. */
  7980. cond = NULL_TREE;
  7981. device = build_int_cst (integer_type_node, GOMP_DEVICE_ICV);
  7982. c = find_omp_clause (clauses, OMP_CLAUSE_IF);
  7983. if (c)
  7984. cond = OMP_CLAUSE_IF_EXPR (c);
  7985. c = find_omp_clause (clauses, OMP_CLAUSE_DEVICE);
  7986. if (c)
  7987. {
  7988. /* Even if we pass it to all library function calls, it is currently only
  7989. defined/used for the OpenMP target ones. */
  7990. gcc_checking_assert (start_ix == BUILT_IN_GOMP_TARGET
  7991. || start_ix == BUILT_IN_GOMP_TARGET_DATA
  7992. || start_ix == BUILT_IN_GOMP_TARGET_UPDATE);
  7993. device = OMP_CLAUSE_DEVICE_ID (c);
  7994. clause_loc = OMP_CLAUSE_LOCATION (c);
  7995. }
  7996. else
  7997. clause_loc = gimple_location (entry_stmt);
  7998. /* Ensure 'device' is of the correct type. */
  7999. device = fold_convert_loc (clause_loc, integer_type_node, device);
  8000. /* If we found the clause 'if (cond)', build
  8001. (cond ? device : GOMP_DEVICE_HOST_FALLBACK). */
  8002. if (cond)
  8003. {
  8004. cond = gimple_boolify (cond);
  8005. basic_block cond_bb, then_bb, else_bb;
  8006. edge e;
  8007. tree tmp_var;
  8008. tmp_var = create_tmp_var (TREE_TYPE (device));
  8009. if (offloaded)
  8010. e = split_block (new_bb, NULL);
  8011. else
  8012. {
  8013. gsi = gsi_last_bb (new_bb);
  8014. gsi_prev (&gsi);
  8015. e = split_block (new_bb, gsi_stmt (gsi));
  8016. }
  8017. cond_bb = e->src;
  8018. new_bb = e->dest;
  8019. remove_edge (e);
  8020. then_bb = create_empty_bb (cond_bb);
  8021. else_bb = create_empty_bb (then_bb);
  8022. set_immediate_dominator (CDI_DOMINATORS, then_bb, cond_bb);
  8023. set_immediate_dominator (CDI_DOMINATORS, else_bb, cond_bb);
  8024. stmt = gimple_build_cond_empty (cond);
  8025. gsi = gsi_last_bb (cond_bb);
  8026. gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
  8027. gsi = gsi_start_bb (then_bb);
  8028. stmt = gimple_build_assign (tmp_var, device);
  8029. gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
  8030. gsi = gsi_start_bb (else_bb);
  8031. stmt = gimple_build_assign (tmp_var,
  8032. build_int_cst (integer_type_node,
  8033. GOMP_DEVICE_HOST_FALLBACK));
  8034. gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
  8035. make_edge (cond_bb, then_bb, EDGE_TRUE_VALUE);
  8036. make_edge (cond_bb, else_bb, EDGE_FALSE_VALUE);
  8037. add_bb_to_loop (then_bb, cond_bb->loop_father);
  8038. add_bb_to_loop (else_bb, cond_bb->loop_father);
  8039. make_edge (then_bb, new_bb, EDGE_FALLTHRU);
  8040. make_edge (else_bb, new_bb, EDGE_FALLTHRU);
  8041. device = tmp_var;
  8042. }
  8043. gsi = gsi_last_bb (new_bb);
  8044. t = gimple_omp_target_data_arg (entry_stmt);
  8045. if (t == NULL)
  8046. {
  8047. t1 = size_zero_node;
  8048. t2 = build_zero_cst (ptr_type_node);
  8049. t3 = t2;
  8050. t4 = t2;
  8051. }
  8052. else
  8053. {
  8054. t1 = TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (TREE_VEC_ELT (t, 1))));
  8055. t1 = size_binop (PLUS_EXPR, t1, size_int (1));
  8056. t2 = build_fold_addr_expr (TREE_VEC_ELT (t, 0));
  8057. t3 = build_fold_addr_expr (TREE_VEC_ELT (t, 1));
  8058. t4 = build_fold_addr_expr (TREE_VEC_ELT (t, 2));
  8059. }
  8060. gimple g;
  8061. /* The maximum number used by any start_ix, without varargs. */
  8062. auto_vec<tree, 11> args;
  8063. args.quick_push (device);
  8064. if (offloaded)
  8065. args.quick_push (build_fold_addr_expr (child_fn));
  8066. switch (start_ix)
  8067. {
  8068. case BUILT_IN_GOMP_TARGET:
  8069. case BUILT_IN_GOMP_TARGET_DATA:
  8070. case BUILT_IN_GOMP_TARGET_UPDATE:
  8071. /* This const void * is part of the current ABI, but we're not actually
  8072. using it. */
  8073. args.quick_push (build_zero_cst (ptr_type_node));
  8074. break;
  8075. case BUILT_IN_GOACC_DATA_START:
  8076. case BUILT_IN_GOACC_ENTER_EXIT_DATA:
  8077. case BUILT_IN_GOACC_PARALLEL:
  8078. case BUILT_IN_GOACC_UPDATE:
  8079. break;
  8080. default:
  8081. gcc_unreachable ();
  8082. }
  8083. args.quick_push (t1);
  8084. args.quick_push (t2);
  8085. args.quick_push (t3);
  8086. args.quick_push (t4);
  8087. switch (start_ix)
  8088. {
  8089. case BUILT_IN_GOACC_DATA_START:
  8090. case BUILT_IN_GOMP_TARGET:
  8091. case BUILT_IN_GOMP_TARGET_DATA:
  8092. case BUILT_IN_GOMP_TARGET_UPDATE:
  8093. break;
  8094. case BUILT_IN_GOACC_PARALLEL:
  8095. {
  8096. tree t_num_gangs, t_num_workers, t_vector_length;
  8097. /* Default values for num_gangs, num_workers, and vector_length. */
  8098. t_num_gangs = t_num_workers = t_vector_length
  8099. = fold_convert_loc (gimple_location (entry_stmt),
  8100. integer_type_node, integer_one_node);
  8101. /* ..., but if present, use the value specified by the respective
  8102. clause, making sure that are of the correct type. */
  8103. c = find_omp_clause (clauses, OMP_CLAUSE_NUM_GANGS);
  8104. if (c)
  8105. t_num_gangs = fold_convert_loc (OMP_CLAUSE_LOCATION (c),
  8106. integer_type_node,
  8107. OMP_CLAUSE_NUM_GANGS_EXPR (c));
  8108. c = find_omp_clause (clauses, OMP_CLAUSE_NUM_WORKERS);
  8109. if (c)
  8110. t_num_workers = fold_convert_loc (OMP_CLAUSE_LOCATION (c),
  8111. integer_type_node,
  8112. OMP_CLAUSE_NUM_WORKERS_EXPR (c));
  8113. c = find_omp_clause (clauses, OMP_CLAUSE_VECTOR_LENGTH);
  8114. if (c)
  8115. t_vector_length = fold_convert_loc (OMP_CLAUSE_LOCATION (c),
  8116. integer_type_node,
  8117. OMP_CLAUSE_VECTOR_LENGTH_EXPR (c));
  8118. args.quick_push (t_num_gangs);
  8119. args.quick_push (t_num_workers);
  8120. args.quick_push (t_vector_length);
  8121. }
  8122. /* FALLTHRU */
  8123. case BUILT_IN_GOACC_ENTER_EXIT_DATA:
  8124. case BUILT_IN_GOACC_UPDATE:
  8125. {
  8126. tree t_async;
  8127. int t_wait_idx;
  8128. /* Default values for t_async. */
  8129. t_async = fold_convert_loc (gimple_location (entry_stmt),
  8130. integer_type_node,
  8131. build_int_cst (integer_type_node,
  8132. GOMP_ASYNC_SYNC));
  8133. /* ..., but if present, use the value specified by the respective
  8134. clause, making sure that is of the correct type. */
  8135. c = find_omp_clause (clauses, OMP_CLAUSE_ASYNC);
  8136. if (c)
  8137. t_async = fold_convert_loc (OMP_CLAUSE_LOCATION (c),
  8138. integer_type_node,
  8139. OMP_CLAUSE_ASYNC_EXPR (c));
  8140. args.quick_push (t_async);
  8141. /* Save the index, and... */
  8142. t_wait_idx = args.length ();
  8143. /* ... push a default value. */
  8144. args.quick_push (fold_convert_loc (gimple_location (entry_stmt),
  8145. integer_type_node,
  8146. integer_zero_node));
  8147. c = find_omp_clause (clauses, OMP_CLAUSE_WAIT);
  8148. if (c)
  8149. {
  8150. int n = 0;
  8151. for (; c; c = OMP_CLAUSE_CHAIN (c))
  8152. {
  8153. if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_WAIT)
  8154. {
  8155. args.safe_push (fold_convert_loc (OMP_CLAUSE_LOCATION (c),
  8156. integer_type_node,
  8157. OMP_CLAUSE_WAIT_EXPR (c)));
  8158. n++;
  8159. }
  8160. }
  8161. /* Now that we know the number, replace the default value. */
  8162. args.ordered_remove (t_wait_idx);
  8163. args.quick_insert (t_wait_idx,
  8164. fold_convert_loc (gimple_location (entry_stmt),
  8165. integer_type_node,
  8166. build_int_cst (integer_type_node, n)));
  8167. }
  8168. }
  8169. break;
  8170. default:
  8171. gcc_unreachable ();
  8172. }
  8173. g = gimple_build_call_vec (builtin_decl_explicit (start_ix), args);
  8174. gimple_set_location (g, gimple_location (entry_stmt));
  8175. gsi_insert_before (&gsi, g, GSI_SAME_STMT);
  8176. if (!offloaded)
  8177. {
  8178. g = gsi_stmt (gsi);
  8179. gcc_assert (g && gimple_code (g) == GIMPLE_OMP_TARGET);
  8180. gsi_remove (&gsi, true);
  8181. }
  8182. if (data_region
  8183. && region->exit)
  8184. {
  8185. gsi = gsi_last_bb (region->exit);
  8186. g = gsi_stmt (gsi);
  8187. gcc_assert (g && gimple_code (g) == GIMPLE_OMP_RETURN);
  8188. gsi_remove (&gsi, true);
  8189. }
  8190. }
  8191. /* Expand the parallel region tree rooted at REGION. Expansion
  8192. proceeds in depth-first order. Innermost regions are expanded
  8193. first. This way, parallel regions that require a new function to
  8194. be created (e.g., GIMPLE_OMP_PARALLEL) can be expanded without having any
  8195. internal dependencies in their body. */
  8196. static void
  8197. expand_omp (struct omp_region *region)
  8198. {
  8199. while (region)
  8200. {
  8201. location_t saved_location;
  8202. gimple inner_stmt = NULL;
  8203. /* First, determine whether this is a combined parallel+workshare
  8204. region. */
  8205. if (region->type == GIMPLE_OMP_PARALLEL)
  8206. determine_parallel_type (region);
  8207. if (region->type == GIMPLE_OMP_FOR
  8208. && gimple_omp_for_combined_p (last_stmt (region->entry)))
  8209. inner_stmt = last_stmt (region->inner->entry);
  8210. if (region->inner)
  8211. expand_omp (region->inner);
  8212. saved_location = input_location;
  8213. if (gimple_has_location (last_stmt (region->entry)))
  8214. input_location = gimple_location (last_stmt (region->entry));
  8215. switch (region->type)
  8216. {
  8217. case GIMPLE_OMP_PARALLEL:
  8218. case GIMPLE_OMP_TASK:
  8219. expand_omp_taskreg (region);
  8220. break;
  8221. case GIMPLE_OMP_FOR:
  8222. expand_omp_for (region, inner_stmt);
  8223. break;
  8224. case GIMPLE_OMP_SECTIONS:
  8225. expand_omp_sections (region);
  8226. break;
  8227. case GIMPLE_OMP_SECTION:
  8228. /* Individual omp sections are handled together with their
  8229. parent GIMPLE_OMP_SECTIONS region. */
  8230. break;
  8231. case GIMPLE_OMP_SINGLE:
  8232. expand_omp_single (region);
  8233. break;
  8234. case GIMPLE_OMP_MASTER:
  8235. case GIMPLE_OMP_TASKGROUP:
  8236. case GIMPLE_OMP_ORDERED:
  8237. case GIMPLE_OMP_CRITICAL:
  8238. case GIMPLE_OMP_TEAMS:
  8239. expand_omp_synch (region);
  8240. break;
  8241. case GIMPLE_OMP_ATOMIC_LOAD:
  8242. expand_omp_atomic (region);
  8243. break;
  8244. case GIMPLE_OMP_TARGET:
  8245. expand_omp_target (region);
  8246. break;
  8247. default:
  8248. gcc_unreachable ();
  8249. }
  8250. input_location = saved_location;
  8251. region = region->next;
  8252. }
  8253. }
  8254. /* Helper for build_omp_regions. Scan the dominator tree starting at
  8255. block BB. PARENT is the region that contains BB. If SINGLE_TREE is
  8256. true, the function ends once a single tree is built (otherwise, whole
  8257. forest of OMP constructs may be built). */
  8258. static void
  8259. build_omp_regions_1 (basic_block bb, struct omp_region *parent,
  8260. bool single_tree)
  8261. {
  8262. gimple_stmt_iterator gsi;
  8263. gimple stmt;
  8264. basic_block son;
  8265. gsi = gsi_last_bb (bb);
  8266. if (!gsi_end_p (gsi) && is_gimple_omp (gsi_stmt (gsi)))
  8267. {
  8268. struct omp_region *region;
  8269. enum gimple_code code;
  8270. stmt = gsi_stmt (gsi);
  8271. code = gimple_code (stmt);
  8272. if (code == GIMPLE_OMP_RETURN)
  8273. {
  8274. /* STMT is the return point out of region PARENT. Mark it
  8275. as the exit point and make PARENT the immediately
  8276. enclosing region. */
  8277. gcc_assert (parent);
  8278. region = parent;
  8279. region->exit = bb;
  8280. parent = parent->outer;
  8281. }
  8282. else if (code == GIMPLE_OMP_ATOMIC_STORE)
  8283. {
  8284. /* GIMPLE_OMP_ATOMIC_STORE is analoguous to
  8285. GIMPLE_OMP_RETURN, but matches with
  8286. GIMPLE_OMP_ATOMIC_LOAD. */
  8287. gcc_assert (parent);
  8288. gcc_assert (parent->type == GIMPLE_OMP_ATOMIC_LOAD);
  8289. region = parent;
  8290. region->exit = bb;
  8291. parent = parent->outer;
  8292. }
  8293. else if (code == GIMPLE_OMP_CONTINUE)
  8294. {
  8295. gcc_assert (parent);
  8296. parent->cont = bb;
  8297. }
  8298. else if (code == GIMPLE_OMP_SECTIONS_SWITCH)
  8299. {
  8300. /* GIMPLE_OMP_SECTIONS_SWITCH is part of
  8301. GIMPLE_OMP_SECTIONS, and we do nothing for it. */
  8302. }
  8303. else
  8304. {
  8305. region = new_omp_region (bb, code, parent);
  8306. /* Otherwise... */
  8307. if (code == GIMPLE_OMP_TARGET)
  8308. {
  8309. switch (gimple_omp_target_kind (stmt))
  8310. {
  8311. case GF_OMP_TARGET_KIND_REGION:
  8312. case GF_OMP_TARGET_KIND_DATA:
  8313. case GF_OMP_TARGET_KIND_OACC_PARALLEL:
  8314. case GF_OMP_TARGET_KIND_OACC_KERNELS:
  8315. case GF_OMP_TARGET_KIND_OACC_DATA:
  8316. break;
  8317. case GF_OMP_TARGET_KIND_UPDATE:
  8318. case GF_OMP_TARGET_KIND_OACC_UPDATE:
  8319. case GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA:
  8320. /* ..., other than for those stand-alone directives... */
  8321. region = NULL;
  8322. break;
  8323. default:
  8324. gcc_unreachable ();
  8325. }
  8326. }
  8327. /* ..., this directive becomes the parent for a new region. */
  8328. if (region)
  8329. parent = region;
  8330. }
  8331. }
  8332. if (single_tree && !parent)
  8333. return;
  8334. for (son = first_dom_son (CDI_DOMINATORS, bb);
  8335. son;
  8336. son = next_dom_son (CDI_DOMINATORS, son))
  8337. build_omp_regions_1 (son, parent, single_tree);
  8338. }
  8339. /* Builds the tree of OMP regions rooted at ROOT, storing it to
  8340. root_omp_region. */
  8341. static void
  8342. build_omp_regions_root (basic_block root)
  8343. {
  8344. gcc_assert (root_omp_region == NULL);
  8345. build_omp_regions_1 (root, NULL, true);
  8346. gcc_assert (root_omp_region != NULL);
  8347. }
  8348. /* Expands omp construct (and its subconstructs) starting in HEAD. */
  8349. void
  8350. omp_expand_local (basic_block head)
  8351. {
  8352. build_omp_regions_root (head);
  8353. if (dump_file && (dump_flags & TDF_DETAILS))
  8354. {
  8355. fprintf (dump_file, "\nOMP region tree\n\n");
  8356. dump_omp_region (dump_file, root_omp_region, 0);
  8357. fprintf (dump_file, "\n");
  8358. }
  8359. remove_exit_barriers (root_omp_region);
  8360. expand_omp (root_omp_region);
  8361. free_omp_regions ();
  8362. }
  8363. /* Scan the CFG and build a tree of OMP regions. Return the root of
  8364. the OMP region tree. */
  8365. static void
  8366. build_omp_regions (void)
  8367. {
  8368. gcc_assert (root_omp_region == NULL);
  8369. calculate_dominance_info (CDI_DOMINATORS);
  8370. build_omp_regions_1 (ENTRY_BLOCK_PTR_FOR_FN (cfun), NULL, false);
  8371. }
  8372. /* Main entry point for expanding OMP-GIMPLE into runtime calls. */
  8373. static unsigned int
  8374. execute_expand_omp (void)
  8375. {
  8376. build_omp_regions ();
  8377. if (!root_omp_region)
  8378. return 0;
  8379. if (dump_file)
  8380. {
  8381. fprintf (dump_file, "\nOMP region tree\n\n");
  8382. dump_omp_region (dump_file, root_omp_region, 0);
  8383. fprintf (dump_file, "\n");
  8384. }
  8385. remove_exit_barriers (root_omp_region);
  8386. expand_omp (root_omp_region);
  8387. cleanup_tree_cfg ();
  8388. free_omp_regions ();
  8389. return 0;
  8390. }
  8391. /* OMP expansion -- the default pass, run before creation of SSA form. */
  8392. namespace {
  8393. const pass_data pass_data_expand_omp =
  8394. {
  8395. GIMPLE_PASS, /* type */
  8396. "ompexp", /* name */
  8397. OPTGROUP_NONE, /* optinfo_flags */
  8398. TV_NONE, /* tv_id */
  8399. PROP_gimple_any, /* properties_required */
  8400. PROP_gimple_eomp, /* properties_provided */
  8401. 0, /* properties_destroyed */
  8402. 0, /* todo_flags_start */
  8403. 0, /* todo_flags_finish */
  8404. };
  8405. class pass_expand_omp : public gimple_opt_pass
  8406. {
  8407. public:
  8408. pass_expand_omp (gcc::context *ctxt)
  8409. : gimple_opt_pass (pass_data_expand_omp, ctxt)
  8410. {}
  8411. /* opt_pass methods: */
  8412. virtual unsigned int execute (function *)
  8413. {
  8414. bool gate = ((flag_cilkplus != 0 || flag_openacc != 0 || flag_openmp != 0
  8415. || flag_openmp_simd != 0)
  8416. && !seen_error ());
  8417. /* This pass always runs, to provide PROP_gimple_eomp.
  8418. But often, there is nothing to do. */
  8419. if (!gate)
  8420. return 0;
  8421. return execute_expand_omp ();
  8422. }
  8423. }; // class pass_expand_omp
  8424. } // anon namespace
  8425. gimple_opt_pass *
  8426. make_pass_expand_omp (gcc::context *ctxt)
  8427. {
  8428. return new pass_expand_omp (ctxt);
  8429. }
  8430. namespace {
  8431. const pass_data pass_data_expand_omp_ssa =
  8432. {
  8433. GIMPLE_PASS, /* type */
  8434. "ompexpssa", /* name */
  8435. OPTGROUP_NONE, /* optinfo_flags */
  8436. TV_NONE, /* tv_id */
  8437. PROP_cfg | PROP_ssa, /* properties_required */
  8438. PROP_gimple_eomp, /* properties_provided */
  8439. 0, /* properties_destroyed */
  8440. 0, /* todo_flags_start */
  8441. TODO_cleanup_cfg | TODO_rebuild_alias, /* todo_flags_finish */
  8442. };
  8443. class pass_expand_omp_ssa : public gimple_opt_pass
  8444. {
  8445. public:
  8446. pass_expand_omp_ssa (gcc::context *ctxt)
  8447. : gimple_opt_pass (pass_data_expand_omp_ssa, ctxt)
  8448. {}
  8449. /* opt_pass methods: */
  8450. virtual bool gate (function *fun)
  8451. {
  8452. return !(fun->curr_properties & PROP_gimple_eomp);
  8453. }
  8454. virtual unsigned int execute (function *) { return execute_expand_omp (); }
  8455. }; // class pass_expand_omp_ssa
  8456. } // anon namespace
  8457. gimple_opt_pass *
  8458. make_pass_expand_omp_ssa (gcc::context *ctxt)
  8459. {
  8460. return new pass_expand_omp_ssa (ctxt);
  8461. }
  8462. /* Routines to lower OMP directives into OMP-GIMPLE. */
  8463. /* Helper function to preform, potentially COMPLEX_TYPE, operation and
  8464. convert it to gimple. */
  8465. static void
  8466. oacc_gimple_assign (tree dest, tree_code op, tree src, gimple_seq *seq)
  8467. {
  8468. gimple stmt;
  8469. if (TREE_CODE (TREE_TYPE (dest)) != COMPLEX_TYPE)
  8470. {
  8471. stmt = gimple_build_assign (dest, op, dest, src);
  8472. gimple_seq_add_stmt (seq, stmt);
  8473. return;
  8474. }
  8475. tree t = create_tmp_var (TREE_TYPE (TREE_TYPE (dest)));
  8476. tree rdest = fold_build1 (REALPART_EXPR, TREE_TYPE (TREE_TYPE (dest)), dest);
  8477. gimplify_assign (t, rdest, seq);
  8478. rdest = t;
  8479. t = create_tmp_var (TREE_TYPE (TREE_TYPE (dest)));
  8480. tree idest = fold_build1 (IMAGPART_EXPR, TREE_TYPE (TREE_TYPE (dest)), dest);
  8481. gimplify_assign (t, idest, seq);
  8482. idest = t;
  8483. t = create_tmp_var (TREE_TYPE (TREE_TYPE (src)));
  8484. tree rsrc = fold_build1 (REALPART_EXPR, TREE_TYPE (TREE_TYPE (src)), src);
  8485. gimplify_assign (t, rsrc, seq);
  8486. rsrc = t;
  8487. t = create_tmp_var (TREE_TYPE (TREE_TYPE (src)));
  8488. tree isrc = fold_build1 (IMAGPART_EXPR, TREE_TYPE (TREE_TYPE (src)), src);
  8489. gimplify_assign (t, isrc, seq);
  8490. isrc = t;
  8491. tree r = create_tmp_var (TREE_TYPE (TREE_TYPE (dest)));
  8492. tree i = create_tmp_var (TREE_TYPE (TREE_TYPE (dest)));
  8493. tree result;
  8494. if (op == PLUS_EXPR)
  8495. {
  8496. stmt = gimple_build_assign (r, op, rdest, rsrc);
  8497. gimple_seq_add_stmt (seq, stmt);
  8498. stmt = gimple_build_assign (i, op, idest, isrc);
  8499. gimple_seq_add_stmt (seq, stmt);
  8500. }
  8501. else if (op == MULT_EXPR)
  8502. {
  8503. /* Let x = a + ib = dest, y = c + id = src.
  8504. x * y = (ac - bd) + i(ad + bc) */
  8505. tree ac = create_tmp_var (TREE_TYPE (TREE_TYPE (dest)));
  8506. tree bd = create_tmp_var (TREE_TYPE (TREE_TYPE (dest)));
  8507. tree ad = create_tmp_var (TREE_TYPE (TREE_TYPE (dest)));
  8508. tree bc = create_tmp_var (TREE_TYPE (TREE_TYPE (dest)));
  8509. stmt = gimple_build_assign (ac, MULT_EXPR, rdest, rsrc);
  8510. gimple_seq_add_stmt (seq, stmt);
  8511. stmt = gimple_build_assign (bd, MULT_EXPR, idest, isrc);
  8512. gimple_seq_add_stmt (seq, stmt);
  8513. stmt = gimple_build_assign (r, MINUS_EXPR, ac, bd);
  8514. gimple_seq_add_stmt (seq, stmt);
  8515. stmt = gimple_build_assign (ad, MULT_EXPR, rdest, isrc);
  8516. gimple_seq_add_stmt (seq, stmt);
  8517. stmt = gimple_build_assign (bd, MULT_EXPR, idest, rsrc);
  8518. gimple_seq_add_stmt (seq, stmt);
  8519. stmt = gimple_build_assign (i, PLUS_EXPR, ad, bc);
  8520. gimple_seq_add_stmt (seq, stmt);
  8521. }
  8522. else
  8523. gcc_unreachable ();
  8524. result = build2 (COMPLEX_EXPR, TREE_TYPE (dest), r, i);
  8525. gimplify_assign (dest, result, seq);
  8526. }
  8527. /* Helper function to initialize local data for the reduction arrays.
  8528. The reduction arrays need to be placed inside the calling function
  8529. for accelerators, or else the host won't be able to preform the final
  8530. reduction. */
  8531. static void
  8532. oacc_initialize_reduction_data (tree clauses, tree nthreads,
  8533. gimple_seq *stmt_seqp, omp_context *ctx)
  8534. {
  8535. tree c, t, oc;
  8536. gimple stmt;
  8537. omp_context *octx;
  8538. /* Find the innermost OpenACC parallel context. */
  8539. if (gimple_code (ctx->stmt) == GIMPLE_OMP_TARGET
  8540. && (gimple_omp_target_kind (ctx->stmt)
  8541. == GF_OMP_TARGET_KIND_OACC_PARALLEL))
  8542. octx = ctx;
  8543. else
  8544. octx = ctx->outer;
  8545. gcc_checking_assert (gimple_code (octx->stmt) == GIMPLE_OMP_TARGET
  8546. && (gimple_omp_target_kind (octx->stmt)
  8547. == GF_OMP_TARGET_KIND_OACC_PARALLEL));
  8548. /* Extract the clauses. */
  8549. oc = gimple_omp_target_clauses (octx->stmt);
  8550. /* Find the last outer clause. */
  8551. for (; oc && OMP_CLAUSE_CHAIN (oc); oc = OMP_CLAUSE_CHAIN (oc))
  8552. ;
  8553. /* Allocate arrays for each reduction variable. */
  8554. for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
  8555. {
  8556. if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION)
  8557. continue;
  8558. tree var = OMP_CLAUSE_DECL (c);
  8559. tree type = get_base_type (var);
  8560. tree array = lookup_oacc_reduction (oacc_get_reduction_array_id (var),
  8561. ctx);
  8562. tree size, call;
  8563. /* Calculate size of the reduction array. */
  8564. t = create_tmp_var (TREE_TYPE (nthreads));
  8565. stmt = gimple_build_assign (t, MULT_EXPR, nthreads,
  8566. fold_convert (TREE_TYPE (nthreads),
  8567. TYPE_SIZE_UNIT (type)));
  8568. gimple_seq_add_stmt (stmt_seqp, stmt);
  8569. size = create_tmp_var (sizetype);
  8570. gimplify_assign (size, fold_build1 (NOP_EXPR, sizetype, t), stmt_seqp);
  8571. /* Now allocate memory for it. */
  8572. call = unshare_expr (builtin_decl_explicit (BUILT_IN_ALLOCA));
  8573. stmt = gimple_build_call (call, 1, size);
  8574. gimple_call_set_lhs (stmt, array);
  8575. gimple_seq_add_stmt (stmt_seqp, stmt);
  8576. /* Map this array into the accelerator. */
  8577. /* Add the reduction array to the list of clauses. */
  8578. tree x = array;
  8579. t = build_omp_clause (gimple_location (ctx->stmt), OMP_CLAUSE_MAP);
  8580. OMP_CLAUSE_SET_MAP_KIND (t, GOMP_MAP_FORCE_FROM);
  8581. OMP_CLAUSE_DECL (t) = x;
  8582. OMP_CLAUSE_CHAIN (t) = NULL;
  8583. if (oc)
  8584. OMP_CLAUSE_CHAIN (oc) = t;
  8585. else
  8586. gimple_omp_target_set_clauses (as_a <gomp_target *> (octx->stmt), t);
  8587. OMP_CLAUSE_SIZE (t) = size;
  8588. oc = t;
  8589. }
  8590. }
  8591. /* Helper function to process the array of partial reductions. Nthreads
  8592. indicates the number of threads. Unfortunately, GOACC_GET_NUM_THREADS
  8593. cannot be used here, because nthreads on the host may be different than
  8594. on the accelerator. */
  8595. static void
  8596. oacc_finalize_reduction_data (tree clauses, tree nthreads,
  8597. gimple_seq *stmt_seqp, omp_context *ctx)
  8598. {
  8599. tree c, x, var, array, loop_header, loop_body, loop_exit, type;
  8600. gimple stmt;
  8601. /* Create for loop.
  8602. let var = the original reduction variable
  8603. let array = reduction variable array
  8604. for (i = 0; i < nthreads; i++)
  8605. var op= array[i]
  8606. */
  8607. loop_header = create_artificial_label (UNKNOWN_LOCATION);
  8608. loop_body = create_artificial_label (UNKNOWN_LOCATION);
  8609. loop_exit = create_artificial_label (UNKNOWN_LOCATION);
  8610. /* Create and initialize an index variable. */
  8611. tree ix = create_tmp_var (sizetype);
  8612. gimplify_assign (ix, fold_build1 (NOP_EXPR, sizetype, integer_zero_node),
  8613. stmt_seqp);
  8614. /* Insert the loop header label here. */
  8615. gimple_seq_add_stmt (stmt_seqp, gimple_build_label (loop_header));
  8616. /* Exit loop if ix >= nthreads. */
  8617. x = create_tmp_var (sizetype);
  8618. gimplify_assign (x, fold_build1 (NOP_EXPR, sizetype, nthreads), stmt_seqp);
  8619. stmt = gimple_build_cond (GE_EXPR, ix, x, loop_exit, loop_body);
  8620. gimple_seq_add_stmt (stmt_seqp, stmt);
  8621. /* Insert the loop body label here. */
  8622. gimple_seq_add_stmt (stmt_seqp, gimple_build_label (loop_body));
  8623. /* Collapse each reduction array, one element at a time. */
  8624. for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
  8625. {
  8626. if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION)
  8627. continue;
  8628. tree_code reduction_code = OMP_CLAUSE_REDUCTION_CODE (c);
  8629. /* reduction(-:var) sums up the partial results, so it acts
  8630. identically to reduction(+:var). */
  8631. if (reduction_code == MINUS_EXPR)
  8632. reduction_code = PLUS_EXPR;
  8633. /* Set up reduction variable var. */
  8634. var = OMP_CLAUSE_DECL (c);
  8635. type = get_base_type (var);
  8636. array = lookup_oacc_reduction (oacc_get_reduction_array_id
  8637. (OMP_CLAUSE_DECL (c)), ctx);
  8638. /* Calculate the array offset. */
  8639. tree offset = create_tmp_var (sizetype);
  8640. gimplify_assign (offset, TYPE_SIZE_UNIT (type), stmt_seqp);
  8641. stmt = gimple_build_assign (offset, MULT_EXPR, offset, ix);
  8642. gimple_seq_add_stmt (stmt_seqp, stmt);
  8643. tree ptr = create_tmp_var (TREE_TYPE (array));
  8644. stmt = gimple_build_assign (ptr, POINTER_PLUS_EXPR, array, offset);
  8645. gimple_seq_add_stmt (stmt_seqp, stmt);
  8646. /* Extract array[ix] into mem. */
  8647. tree mem = create_tmp_var (type);
  8648. gimplify_assign (mem, build_simple_mem_ref (ptr), stmt_seqp);
  8649. /* Find the original reduction variable. */
  8650. if (is_reference (var))
  8651. var = build_simple_mem_ref (var);
  8652. tree t = create_tmp_var (type);
  8653. x = lang_hooks.decls.omp_clause_assign_op (c, t, var);
  8654. gimplify_and_add (unshare_expr(x), stmt_seqp);
  8655. /* var = var op mem */
  8656. switch (OMP_CLAUSE_REDUCTION_CODE (c))
  8657. {
  8658. case TRUTH_ANDIF_EXPR:
  8659. case TRUTH_ORIF_EXPR:
  8660. t = fold_build2 (OMP_CLAUSE_REDUCTION_CODE (c), integer_type_node,
  8661. t, mem);
  8662. gimplify_and_add (t, stmt_seqp);
  8663. break;
  8664. default:
  8665. /* The lhs isn't a gimple_reg when var is COMPLEX_TYPE. */
  8666. oacc_gimple_assign (t, OMP_CLAUSE_REDUCTION_CODE (c), mem,
  8667. stmt_seqp);
  8668. }
  8669. t = fold_build1 (NOP_EXPR, TREE_TYPE (var), t);
  8670. x = lang_hooks.decls.omp_clause_assign_op (c, var, t);
  8671. gimplify_and_add (unshare_expr(x), stmt_seqp);
  8672. }
  8673. /* Increment the induction variable. */
  8674. tree one = fold_build1 (NOP_EXPR, sizetype, integer_one_node);
  8675. stmt = gimple_build_assign (ix, PLUS_EXPR, ix, one);
  8676. gimple_seq_add_stmt (stmt_seqp, stmt);
  8677. /* Go back to the top of the loop. */
  8678. gimple_seq_add_stmt (stmt_seqp, gimple_build_goto (loop_header));
  8679. /* Place the loop exit label here. */
  8680. gimple_seq_add_stmt (stmt_seqp, gimple_build_label (loop_exit));
  8681. }
  8682. /* Scan through all of the gimple stmts searching for an OMP_FOR_EXPR, and
  8683. scan that for reductions. */
  8684. static void
  8685. oacc_process_reduction_data (gimple_seq *body, gimple_seq *in_stmt_seqp,
  8686. gimple_seq *out_stmt_seqp, omp_context *ctx)
  8687. {
  8688. gimple_stmt_iterator gsi;
  8689. gimple_seq inner = NULL;
  8690. /* A collapse clause may have inserted a new bind block. */
  8691. gsi = gsi_start (*body);
  8692. while (!gsi_end_p (gsi))
  8693. {
  8694. gimple stmt = gsi_stmt (gsi);
  8695. if (gbind *bind_stmt = dyn_cast <gbind *> (stmt))
  8696. {
  8697. inner = gimple_bind_body (bind_stmt);
  8698. body = &inner;
  8699. gsi = gsi_start (*body);
  8700. }
  8701. else if (dyn_cast <gomp_for *> (stmt))
  8702. break;
  8703. else
  8704. gsi_next (&gsi);
  8705. }
  8706. for (gsi = gsi_start (*body); !gsi_end_p (gsi); gsi_next (&gsi))
  8707. {
  8708. tree clauses, nthreads, t, c, acc_device, acc_device_host, call,
  8709. enter, exit;
  8710. bool reduction_found = false;
  8711. gimple stmt = gsi_stmt (gsi);
  8712. switch (gimple_code (stmt))
  8713. {
  8714. case GIMPLE_OMP_FOR:
  8715. clauses = gimple_omp_for_clauses (stmt);
  8716. /* Search for a reduction clause. */
  8717. for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
  8718. if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION)
  8719. {
  8720. reduction_found = true;
  8721. break;
  8722. }
  8723. if (!reduction_found)
  8724. break;
  8725. ctx = maybe_lookup_ctx (stmt);
  8726. t = NULL_TREE;
  8727. /* Extract the number of threads. */
  8728. nthreads = create_tmp_var (sizetype);
  8729. t = oacc_max_threads (ctx);
  8730. gimplify_assign (nthreads, t, in_stmt_seqp);
  8731. /* Determine if this is kernel will be executed on the host. */
  8732. call = builtin_decl_explicit (BUILT_IN_ACC_GET_DEVICE_TYPE);
  8733. acc_device = create_tmp_var (integer_type_node, ".acc_device_type");
  8734. stmt = gimple_build_call (call, 0);
  8735. gimple_call_set_lhs (stmt, acc_device);
  8736. gimple_seq_add_stmt (in_stmt_seqp, stmt);
  8737. /* Set nthreads = 1 for ACC_DEVICE_TYPE=host. */
  8738. acc_device_host = create_tmp_var (integer_type_node,
  8739. ".acc_device_host");
  8740. gimplify_assign (acc_device_host,
  8741. build_int_cst (integer_type_node,
  8742. GOMP_DEVICE_HOST),
  8743. in_stmt_seqp);
  8744. enter = create_artificial_label (UNKNOWN_LOCATION);
  8745. exit = create_artificial_label (UNKNOWN_LOCATION);
  8746. stmt = gimple_build_cond (EQ_EXPR, acc_device, acc_device_host,
  8747. enter, exit);
  8748. gimple_seq_add_stmt (in_stmt_seqp, stmt);
  8749. gimple_seq_add_stmt (in_stmt_seqp, gimple_build_label (enter));
  8750. gimplify_assign (nthreads, fold_build1 (NOP_EXPR, sizetype,
  8751. integer_one_node),
  8752. in_stmt_seqp);
  8753. gimple_seq_add_stmt (in_stmt_seqp, gimple_build_label (exit));
  8754. /* Also, set nthreads = 1 for ACC_DEVICE_TYPE=host_nonshm. */
  8755. gimplify_assign (acc_device_host,
  8756. build_int_cst (integer_type_node,
  8757. GOMP_DEVICE_HOST_NONSHM),
  8758. in_stmt_seqp);
  8759. enter = create_artificial_label (UNKNOWN_LOCATION);
  8760. exit = create_artificial_label (UNKNOWN_LOCATION);
  8761. stmt = gimple_build_cond (EQ_EXPR, acc_device, acc_device_host,
  8762. enter, exit);
  8763. gimple_seq_add_stmt (in_stmt_seqp, stmt);
  8764. gimple_seq_add_stmt (in_stmt_seqp, gimple_build_label (enter));
  8765. gimplify_assign (nthreads, fold_build1 (NOP_EXPR, sizetype,
  8766. integer_one_node),
  8767. in_stmt_seqp);
  8768. gimple_seq_add_stmt (in_stmt_seqp, gimple_build_label (exit));
  8769. oacc_initialize_reduction_data (clauses, nthreads, in_stmt_seqp,
  8770. ctx);
  8771. oacc_finalize_reduction_data (clauses, nthreads, out_stmt_seqp, ctx);
  8772. break;
  8773. default:
  8774. // Scan for other directives which support reduction here.
  8775. break;
  8776. }
  8777. }
  8778. }
  8779. /* If ctx is a worksharing context inside of a cancellable parallel
  8780. region and it isn't nowait, add lhs to its GIMPLE_OMP_RETURN
  8781. and conditional branch to parallel's cancel_label to handle
  8782. cancellation in the implicit barrier. */
  8783. static void
  8784. maybe_add_implicit_barrier_cancel (omp_context *ctx, gimple_seq *body)
  8785. {
  8786. gimple omp_return = gimple_seq_last_stmt (*body);
  8787. gcc_assert (gimple_code (omp_return) == GIMPLE_OMP_RETURN);
  8788. if (gimple_omp_return_nowait_p (omp_return))
  8789. return;
  8790. if (ctx->outer
  8791. && gimple_code (ctx->outer->stmt) == GIMPLE_OMP_PARALLEL
  8792. && ctx->outer->cancellable)
  8793. {
  8794. tree fndecl = builtin_decl_explicit (BUILT_IN_GOMP_CANCEL);
  8795. tree c_bool_type = TREE_TYPE (TREE_TYPE (fndecl));
  8796. tree lhs = create_tmp_var (c_bool_type);
  8797. gimple_omp_return_set_lhs (omp_return, lhs);
  8798. tree fallthru_label = create_artificial_label (UNKNOWN_LOCATION);
  8799. gimple g = gimple_build_cond (NE_EXPR, lhs,
  8800. fold_convert (c_bool_type,
  8801. boolean_false_node),
  8802. ctx->outer->cancel_label, fallthru_label);
  8803. gimple_seq_add_stmt (body, g);
  8804. gimple_seq_add_stmt (body, gimple_build_label (fallthru_label));
  8805. }
  8806. }
  8807. /* Lower the OpenMP sections directive in the current statement in GSI_P.
  8808. CTX is the enclosing OMP context for the current statement. */
  8809. static void
  8810. lower_omp_sections (gimple_stmt_iterator *gsi_p, omp_context *ctx)
  8811. {
  8812. tree block, control;
  8813. gimple_stmt_iterator tgsi;
  8814. gomp_sections *stmt;
  8815. gimple t;
  8816. gbind *new_stmt, *bind;
  8817. gimple_seq ilist, dlist, olist, new_body;
  8818. stmt = as_a <gomp_sections *> (gsi_stmt (*gsi_p));
  8819. push_gimplify_context ();
  8820. dlist = NULL;
  8821. ilist = NULL;
  8822. lower_rec_input_clauses (gimple_omp_sections_clauses (stmt),
  8823. &ilist, &dlist, ctx, NULL);
  8824. new_body = gimple_omp_body (stmt);
  8825. gimple_omp_set_body (stmt, NULL);
  8826. tgsi = gsi_start (new_body);
  8827. for (; !gsi_end_p (tgsi); gsi_next (&tgsi))
  8828. {
  8829. omp_context *sctx;
  8830. gimple sec_start;
  8831. sec_start = gsi_stmt (tgsi);
  8832. sctx = maybe_lookup_ctx (sec_start);
  8833. gcc_assert (sctx);
  8834. lower_omp (gimple_omp_body_ptr (sec_start), sctx);
  8835. gsi_insert_seq_after (&tgsi, gimple_omp_body (sec_start),
  8836. GSI_CONTINUE_LINKING);
  8837. gimple_omp_set_body (sec_start, NULL);
  8838. if (gsi_one_before_end_p (tgsi))
  8839. {
  8840. gimple_seq l = NULL;
  8841. lower_lastprivate_clauses (gimple_omp_sections_clauses (stmt), NULL,
  8842. &l, ctx);
  8843. gsi_insert_seq_after (&tgsi, l, GSI_CONTINUE_LINKING);
  8844. gimple_omp_section_set_last (sec_start);
  8845. }
  8846. gsi_insert_after (&tgsi, gimple_build_omp_return (false),
  8847. GSI_CONTINUE_LINKING);
  8848. }
  8849. block = make_node (BLOCK);
  8850. bind = gimple_build_bind (NULL, new_body, block);
  8851. olist = NULL;
  8852. lower_reduction_clauses (gimple_omp_sections_clauses (stmt), &olist, ctx);
  8853. block = make_node (BLOCK);
  8854. new_stmt = gimple_build_bind (NULL, NULL, block);
  8855. gsi_replace (gsi_p, new_stmt, true);
  8856. pop_gimplify_context (new_stmt);
  8857. gimple_bind_append_vars (new_stmt, ctx->block_vars);
  8858. BLOCK_VARS (block) = gimple_bind_vars (bind);
  8859. if (BLOCK_VARS (block))
  8860. TREE_USED (block) = 1;
  8861. new_body = NULL;
  8862. gimple_seq_add_seq (&new_body, ilist);
  8863. gimple_seq_add_stmt (&new_body, stmt);
  8864. gimple_seq_add_stmt (&new_body, gimple_build_omp_sections_switch ());
  8865. gimple_seq_add_stmt (&new_body, bind);
  8866. control = create_tmp_var (unsigned_type_node, ".section");
  8867. t = gimple_build_omp_continue (control, control);
  8868. gimple_omp_sections_set_control (stmt, control);
  8869. gimple_seq_add_stmt (&new_body, t);
  8870. gimple_seq_add_seq (&new_body, olist);
  8871. if (ctx->cancellable)
  8872. gimple_seq_add_stmt (&new_body, gimple_build_label (ctx->cancel_label));
  8873. gimple_seq_add_seq (&new_body, dlist);
  8874. new_body = maybe_catch_exception (new_body);
  8875. t = gimple_build_omp_return
  8876. (!!find_omp_clause (gimple_omp_sections_clauses (stmt),
  8877. OMP_CLAUSE_NOWAIT));
  8878. gimple_seq_add_stmt (&new_body, t);
  8879. maybe_add_implicit_barrier_cancel (ctx, &new_body);
  8880. gimple_bind_set_body (new_stmt, new_body);
  8881. }
  8882. /* A subroutine of lower_omp_single. Expand the simple form of
  8883. a GIMPLE_OMP_SINGLE, without a copyprivate clause:
  8884. if (GOMP_single_start ())
  8885. BODY;
  8886. [ GOMP_barrier (); ] -> unless 'nowait' is present.
  8887. FIXME. It may be better to delay expanding the logic of this until
  8888. pass_expand_omp. The expanded logic may make the job more difficult
  8889. to a synchronization analysis pass. */
  8890. static void
  8891. lower_omp_single_simple (gomp_single *single_stmt, gimple_seq *pre_p)
  8892. {
  8893. location_t loc = gimple_location (single_stmt);
  8894. tree tlabel = create_artificial_label (loc);
  8895. tree flabel = create_artificial_label (loc);
  8896. gimple call, cond;
  8897. tree lhs, decl;
  8898. decl = builtin_decl_explicit (BUILT_IN_GOMP_SINGLE_START);
  8899. lhs = create_tmp_var (TREE_TYPE (TREE_TYPE (decl)));
  8900. call = gimple_build_call (decl, 0);
  8901. gimple_call_set_lhs (call, lhs);
  8902. gimple_seq_add_stmt (pre_p, call);
  8903. cond = gimple_build_cond (EQ_EXPR, lhs,
  8904. fold_convert_loc (loc, TREE_TYPE (lhs),
  8905. boolean_true_node),
  8906. tlabel, flabel);
  8907. gimple_seq_add_stmt (pre_p, cond);
  8908. gimple_seq_add_stmt (pre_p, gimple_build_label (tlabel));
  8909. gimple_seq_add_seq (pre_p, gimple_omp_body (single_stmt));
  8910. gimple_seq_add_stmt (pre_p, gimple_build_label (flabel));
  8911. }
  8912. /* A subroutine of lower_omp_single. Expand the simple form of
  8913. a GIMPLE_OMP_SINGLE, with a copyprivate clause:
  8914. #pragma omp single copyprivate (a, b, c)
  8915. Create a new structure to hold copies of 'a', 'b' and 'c' and emit:
  8916. {
  8917. if ((copyout_p = GOMP_single_copy_start ()) == NULL)
  8918. {
  8919. BODY;
  8920. copyout.a = a;
  8921. copyout.b = b;
  8922. copyout.c = c;
  8923. GOMP_single_copy_end (&copyout);
  8924. }
  8925. else
  8926. {
  8927. a = copyout_p->a;
  8928. b = copyout_p->b;
  8929. c = copyout_p->c;
  8930. }
  8931. GOMP_barrier ();
  8932. }
  8933. FIXME. It may be better to delay expanding the logic of this until
  8934. pass_expand_omp. The expanded logic may make the job more difficult
  8935. to a synchronization analysis pass. */
  8936. static void
  8937. lower_omp_single_copy (gomp_single *single_stmt, gimple_seq *pre_p,
  8938. omp_context *ctx)
  8939. {
  8940. tree ptr_type, t, l0, l1, l2, bfn_decl;
  8941. gimple_seq copyin_seq;
  8942. location_t loc = gimple_location (single_stmt);
  8943. ctx->sender_decl = create_tmp_var (ctx->record_type, ".omp_copy_o");
  8944. ptr_type = build_pointer_type (ctx->record_type);
  8945. ctx->receiver_decl = create_tmp_var (ptr_type, ".omp_copy_i");
  8946. l0 = create_artificial_label (loc);
  8947. l1 = create_artificial_label (loc);
  8948. l2 = create_artificial_label (loc);
  8949. bfn_decl = builtin_decl_explicit (BUILT_IN_GOMP_SINGLE_COPY_START);
  8950. t = build_call_expr_loc (loc, bfn_decl, 0);
  8951. t = fold_convert_loc (loc, ptr_type, t);
  8952. gimplify_assign (ctx->receiver_decl, t, pre_p);
  8953. t = build2 (EQ_EXPR, boolean_type_node, ctx->receiver_decl,
  8954. build_int_cst (ptr_type, 0));
  8955. t = build3 (COND_EXPR, void_type_node, t,
  8956. build_and_jump (&l0), build_and_jump (&l1));
  8957. gimplify_and_add (t, pre_p);
  8958. gimple_seq_add_stmt (pre_p, gimple_build_label (l0));
  8959. gimple_seq_add_seq (pre_p, gimple_omp_body (single_stmt));
  8960. copyin_seq = NULL;
  8961. lower_copyprivate_clauses (gimple_omp_single_clauses (single_stmt), pre_p,
  8962. &copyin_seq, ctx);
  8963. t = build_fold_addr_expr_loc (loc, ctx->sender_decl);
  8964. bfn_decl = builtin_decl_explicit (BUILT_IN_GOMP_SINGLE_COPY_END);
  8965. t = build_call_expr_loc (loc, bfn_decl, 1, t);
  8966. gimplify_and_add (t, pre_p);
  8967. t = build_and_jump (&l2);
  8968. gimplify_and_add (t, pre_p);
  8969. gimple_seq_add_stmt (pre_p, gimple_build_label (l1));
  8970. gimple_seq_add_seq (pre_p, copyin_seq);
  8971. gimple_seq_add_stmt (pre_p, gimple_build_label (l2));
  8972. }
  8973. /* Expand code for an OpenMP single directive. */
  8974. static void
  8975. lower_omp_single (gimple_stmt_iterator *gsi_p, omp_context *ctx)
  8976. {
  8977. tree block;
  8978. gimple t;
  8979. gomp_single *single_stmt = as_a <gomp_single *> (gsi_stmt (*gsi_p));
  8980. gbind *bind;
  8981. gimple_seq bind_body, bind_body_tail = NULL, dlist;
  8982. push_gimplify_context ();
  8983. block = make_node (BLOCK);
  8984. bind = gimple_build_bind (NULL, NULL, block);
  8985. gsi_replace (gsi_p, bind, true);
  8986. bind_body = NULL;
  8987. dlist = NULL;
  8988. lower_rec_input_clauses (gimple_omp_single_clauses (single_stmt),
  8989. &bind_body, &dlist, ctx, NULL);
  8990. lower_omp (gimple_omp_body_ptr (single_stmt), ctx);
  8991. gimple_seq_add_stmt (&bind_body, single_stmt);
  8992. if (ctx->record_type)
  8993. lower_omp_single_copy (single_stmt, &bind_body, ctx);
  8994. else
  8995. lower_omp_single_simple (single_stmt, &bind_body);
  8996. gimple_omp_set_body (single_stmt, NULL);
  8997. gimple_seq_add_seq (&bind_body, dlist);
  8998. bind_body = maybe_catch_exception (bind_body);
  8999. t = gimple_build_omp_return
  9000. (!!find_omp_clause (gimple_omp_single_clauses (single_stmt),
  9001. OMP_CLAUSE_NOWAIT));
  9002. gimple_seq_add_stmt (&bind_body_tail, t);
  9003. maybe_add_implicit_barrier_cancel (ctx, &bind_body_tail);
  9004. if (ctx->record_type)
  9005. {
  9006. gimple_stmt_iterator gsi = gsi_start (bind_body_tail);
  9007. tree clobber = build_constructor (ctx->record_type, NULL);
  9008. TREE_THIS_VOLATILE (clobber) = 1;
  9009. gsi_insert_after (&gsi, gimple_build_assign (ctx->sender_decl,
  9010. clobber), GSI_SAME_STMT);
  9011. }
  9012. gimple_seq_add_seq (&bind_body, bind_body_tail);
  9013. gimple_bind_set_body (bind, bind_body);
  9014. pop_gimplify_context (bind);
  9015. gimple_bind_append_vars (bind, ctx->block_vars);
  9016. BLOCK_VARS (block) = ctx->block_vars;
  9017. if (BLOCK_VARS (block))
  9018. TREE_USED (block) = 1;
  9019. }
  9020. /* Expand code for an OpenMP master directive. */
  9021. static void
  9022. lower_omp_master (gimple_stmt_iterator *gsi_p, omp_context *ctx)
  9023. {
  9024. tree block, lab = NULL, x, bfn_decl;
  9025. gimple stmt = gsi_stmt (*gsi_p);
  9026. gbind *bind;
  9027. location_t loc = gimple_location (stmt);
  9028. gimple_seq tseq;
  9029. push_gimplify_context ();
  9030. block = make_node (BLOCK);
  9031. bind = gimple_build_bind (NULL, NULL, block);
  9032. gsi_replace (gsi_p, bind, true);
  9033. gimple_bind_add_stmt (bind, stmt);
  9034. bfn_decl = builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM);
  9035. x = build_call_expr_loc (loc, bfn_decl, 0);
  9036. x = build2 (EQ_EXPR, boolean_type_node, x, integer_zero_node);
  9037. x = build3 (COND_EXPR, void_type_node, x, NULL, build_and_jump (&lab));
  9038. tseq = NULL;
  9039. gimplify_and_add (x, &tseq);
  9040. gimple_bind_add_seq (bind, tseq);
  9041. lower_omp (gimple_omp_body_ptr (stmt), ctx);
  9042. gimple_omp_set_body (stmt, maybe_catch_exception (gimple_omp_body (stmt)));
  9043. gimple_bind_add_seq (bind, gimple_omp_body (stmt));
  9044. gimple_omp_set_body (stmt, NULL);
  9045. gimple_bind_add_stmt (bind, gimple_build_label (lab));
  9046. gimple_bind_add_stmt (bind, gimple_build_omp_return (true));
  9047. pop_gimplify_context (bind);
  9048. gimple_bind_append_vars (bind, ctx->block_vars);
  9049. BLOCK_VARS (block) = ctx->block_vars;
  9050. }
  9051. /* Expand code for an OpenMP taskgroup directive. */
  9052. static void
  9053. lower_omp_taskgroup (gimple_stmt_iterator *gsi_p, omp_context *ctx)
  9054. {
  9055. gimple stmt = gsi_stmt (*gsi_p);
  9056. gcall *x;
  9057. gbind *bind;
  9058. tree block = make_node (BLOCK);
  9059. bind = gimple_build_bind (NULL, NULL, block);
  9060. gsi_replace (gsi_p, bind, true);
  9061. gimple_bind_add_stmt (bind, stmt);
  9062. x = gimple_build_call (builtin_decl_explicit (BUILT_IN_GOMP_TASKGROUP_START),
  9063. 0);
  9064. gimple_bind_add_stmt (bind, x);
  9065. lower_omp (gimple_omp_body_ptr (stmt), ctx);
  9066. gimple_bind_add_seq (bind, gimple_omp_body (stmt));
  9067. gimple_omp_set_body (stmt, NULL);
  9068. gimple_bind_add_stmt (bind, gimple_build_omp_return (true));
  9069. gimple_bind_append_vars (bind, ctx->block_vars);
  9070. BLOCK_VARS (block) = ctx->block_vars;
  9071. }
  9072. /* Expand code for an OpenMP ordered directive. */
  9073. static void
  9074. lower_omp_ordered (gimple_stmt_iterator *gsi_p, omp_context *ctx)
  9075. {
  9076. tree block;
  9077. gimple stmt = gsi_stmt (*gsi_p);
  9078. gcall *x;
  9079. gbind *bind;
  9080. push_gimplify_context ();
  9081. block = make_node (BLOCK);
  9082. bind = gimple_build_bind (NULL, NULL, block);
  9083. gsi_replace (gsi_p, bind, true);
  9084. gimple_bind_add_stmt (bind, stmt);
  9085. x = gimple_build_call (builtin_decl_explicit (BUILT_IN_GOMP_ORDERED_START),
  9086. 0);
  9087. gimple_bind_add_stmt (bind, x);
  9088. lower_omp (gimple_omp_body_ptr (stmt), ctx);
  9089. gimple_omp_set_body (stmt, maybe_catch_exception (gimple_omp_body (stmt)));
  9090. gimple_bind_add_seq (bind, gimple_omp_body (stmt));
  9091. gimple_omp_set_body (stmt, NULL);
  9092. x = gimple_build_call (builtin_decl_explicit (BUILT_IN_GOMP_ORDERED_END), 0);
  9093. gimple_bind_add_stmt (bind, x);
  9094. gimple_bind_add_stmt (bind, gimple_build_omp_return (true));
  9095. pop_gimplify_context (bind);
  9096. gimple_bind_append_vars (bind, ctx->block_vars);
  9097. BLOCK_VARS (block) = gimple_bind_vars (bind);
  9098. }
  9099. /* Gimplify a GIMPLE_OMP_CRITICAL statement. This is a relatively simple
  9100. substitution of a couple of function calls. But in the NAMED case,
  9101. requires that languages coordinate a symbol name. It is therefore
  9102. best put here in common code. */
  9103. static GTY(()) hash_map<tree, tree> *critical_name_mutexes;
  9104. static void
  9105. lower_omp_critical (gimple_stmt_iterator *gsi_p, omp_context *ctx)
  9106. {
  9107. tree block;
  9108. tree name, lock, unlock;
  9109. gomp_critical *stmt = as_a <gomp_critical *> (gsi_stmt (*gsi_p));
  9110. gbind *bind;
  9111. location_t loc = gimple_location (stmt);
  9112. gimple_seq tbody;
  9113. name = gimple_omp_critical_name (stmt);
  9114. if (name)
  9115. {
  9116. tree decl;
  9117. if (!critical_name_mutexes)
  9118. critical_name_mutexes = hash_map<tree, tree>::create_ggc (10);
  9119. tree *n = critical_name_mutexes->get (name);
  9120. if (n == NULL)
  9121. {
  9122. char *new_str;
  9123. decl = create_tmp_var_raw (ptr_type_node);
  9124. new_str = ACONCAT ((".gomp_critical_user_",
  9125. IDENTIFIER_POINTER (name), NULL));
  9126. DECL_NAME (decl) = get_identifier (new_str);
  9127. TREE_PUBLIC (decl) = 1;
  9128. TREE_STATIC (decl) = 1;
  9129. DECL_COMMON (decl) = 1;
  9130. DECL_ARTIFICIAL (decl) = 1;
  9131. DECL_IGNORED_P (decl) = 1;
  9132. varpool_node::finalize_decl (decl);
  9133. critical_name_mutexes->put (name, decl);
  9134. }
  9135. else
  9136. decl = *n;
  9137. /* If '#pragma omp critical' is inside offloaded region or
  9138. inside function marked as offloadable, the symbol must be
  9139. marked as offloadable too. */
  9140. omp_context *octx;
  9141. if (cgraph_node::get (current_function_decl)->offloadable)
  9142. varpool_node::get_create (decl)->offloadable = 1;
  9143. else
  9144. for (octx = ctx->outer; octx; octx = octx->outer)
  9145. if (is_gimple_omp_offloaded (octx->stmt))
  9146. {
  9147. varpool_node::get_create (decl)->offloadable = 1;
  9148. break;
  9149. }
  9150. lock = builtin_decl_explicit (BUILT_IN_GOMP_CRITICAL_NAME_START);
  9151. lock = build_call_expr_loc (loc, lock, 1, build_fold_addr_expr_loc (loc, decl));
  9152. unlock = builtin_decl_explicit (BUILT_IN_GOMP_CRITICAL_NAME_END);
  9153. unlock = build_call_expr_loc (loc, unlock, 1,
  9154. build_fold_addr_expr_loc (loc, decl));
  9155. }
  9156. else
  9157. {
  9158. lock = builtin_decl_explicit (BUILT_IN_GOMP_CRITICAL_START);
  9159. lock = build_call_expr_loc (loc, lock, 0);
  9160. unlock = builtin_decl_explicit (BUILT_IN_GOMP_CRITICAL_END);
  9161. unlock = build_call_expr_loc (loc, unlock, 0);
  9162. }
  9163. push_gimplify_context ();
  9164. block = make_node (BLOCK);
  9165. bind = gimple_build_bind (NULL, NULL, block);
  9166. gsi_replace (gsi_p, bind, true);
  9167. gimple_bind_add_stmt (bind, stmt);
  9168. tbody = gimple_bind_body (bind);
  9169. gimplify_and_add (lock, &tbody);
  9170. gimple_bind_set_body (bind, tbody);
  9171. lower_omp (gimple_omp_body_ptr (stmt), ctx);
  9172. gimple_omp_set_body (stmt, maybe_catch_exception (gimple_omp_body (stmt)));
  9173. gimple_bind_add_seq (bind, gimple_omp_body (stmt));
  9174. gimple_omp_set_body (stmt, NULL);
  9175. tbody = gimple_bind_body (bind);
  9176. gimplify_and_add (unlock, &tbody);
  9177. gimple_bind_set_body (bind, tbody);
  9178. gimple_bind_add_stmt (bind, gimple_build_omp_return (true));
  9179. pop_gimplify_context (bind);
  9180. gimple_bind_append_vars (bind, ctx->block_vars);
  9181. BLOCK_VARS (block) = gimple_bind_vars (bind);
  9182. }
  9183. /* A subroutine of lower_omp_for. Generate code to emit the predicate
  9184. for a lastprivate clause. Given a loop control predicate of (V
  9185. cond N2), we gate the clause on (!(V cond N2)). The lowered form
  9186. is appended to *DLIST, iterator initialization is appended to
  9187. *BODY_P. */
  9188. static void
  9189. lower_omp_for_lastprivate (struct omp_for_data *fd, gimple_seq *body_p,
  9190. gimple_seq *dlist, struct omp_context *ctx)
  9191. {
  9192. tree clauses, cond, vinit;
  9193. enum tree_code cond_code;
  9194. gimple_seq stmts;
  9195. cond_code = fd->loop.cond_code;
  9196. cond_code = cond_code == LT_EXPR ? GE_EXPR : LE_EXPR;
  9197. /* When possible, use a strict equality expression. This can let VRP
  9198. type optimizations deduce the value and remove a copy. */
  9199. if (tree_fits_shwi_p (fd->loop.step))
  9200. {
  9201. HOST_WIDE_INT step = tree_to_shwi (fd->loop.step);
  9202. if (step == 1 || step == -1)
  9203. cond_code = EQ_EXPR;
  9204. }
  9205. tree n2 = fd->loop.n2;
  9206. if (fd->collapse > 1
  9207. && TREE_CODE (n2) != INTEGER_CST
  9208. && gimple_omp_for_combined_into_p (fd->for_stmt)
  9209. && gimple_code (ctx->outer->stmt) == GIMPLE_OMP_FOR)
  9210. {
  9211. gomp_for *gfor = as_a <gomp_for *> (ctx->outer->stmt);
  9212. if (gimple_omp_for_kind (gfor) == GF_OMP_FOR_KIND_FOR)
  9213. {
  9214. struct omp_for_data outer_fd;
  9215. extract_omp_for_data (gfor, &outer_fd, NULL);
  9216. n2 = fold_convert (TREE_TYPE (n2), outer_fd.loop.n2);
  9217. }
  9218. }
  9219. cond = build2 (cond_code, boolean_type_node, fd->loop.v, n2);
  9220. clauses = gimple_omp_for_clauses (fd->for_stmt);
  9221. stmts = NULL;
  9222. lower_lastprivate_clauses (clauses, cond, &stmts, ctx);
  9223. if (!gimple_seq_empty_p (stmts))
  9224. {
  9225. gimple_seq_add_seq (&stmts, *dlist);
  9226. *dlist = stmts;
  9227. /* Optimize: v = 0; is usually cheaper than v = some_other_constant. */
  9228. vinit = fd->loop.n1;
  9229. if (cond_code == EQ_EXPR
  9230. && tree_fits_shwi_p (fd->loop.n2)
  9231. && ! integer_zerop (fd->loop.n2))
  9232. vinit = build_int_cst (TREE_TYPE (fd->loop.v), 0);
  9233. else
  9234. vinit = unshare_expr (vinit);
  9235. /* Initialize the iterator variable, so that threads that don't execute
  9236. any iterations don't execute the lastprivate clauses by accident. */
  9237. gimplify_assign (fd->loop.v, vinit, body_p);
  9238. }
  9239. }
  9240. /* Lower code for an OMP loop directive. */
  9241. static void
  9242. lower_omp_for (gimple_stmt_iterator *gsi_p, omp_context *ctx)
  9243. {
  9244. tree *rhs_p, block;
  9245. struct omp_for_data fd, *fdp = NULL;
  9246. gomp_for *stmt = as_a <gomp_for *> (gsi_stmt (*gsi_p));
  9247. gbind *new_stmt;
  9248. gimple_seq omp_for_body, body, dlist;
  9249. size_t i;
  9250. push_gimplify_context ();
  9251. lower_omp (gimple_omp_for_pre_body_ptr (stmt), ctx);
  9252. block = make_node (BLOCK);
  9253. new_stmt = gimple_build_bind (NULL, NULL, block);
  9254. /* Replace at gsi right away, so that 'stmt' is no member
  9255. of a sequence anymore as we're going to add to to a different
  9256. one below. */
  9257. gsi_replace (gsi_p, new_stmt, true);
  9258. /* Move declaration of temporaries in the loop body before we make
  9259. it go away. */
  9260. omp_for_body = gimple_omp_body (stmt);
  9261. if (!gimple_seq_empty_p (omp_for_body)
  9262. && gimple_code (gimple_seq_first_stmt (omp_for_body)) == GIMPLE_BIND)
  9263. {
  9264. gbind *inner_bind
  9265. = as_a <gbind *> (gimple_seq_first_stmt (omp_for_body));
  9266. tree vars = gimple_bind_vars (inner_bind);
  9267. gimple_bind_append_vars (new_stmt, vars);
  9268. /* bind_vars/BLOCK_VARS are being moved to new_stmt/block, don't
  9269. keep them on the inner_bind and it's block. */
  9270. gimple_bind_set_vars (inner_bind, NULL_TREE);
  9271. if (gimple_bind_block (inner_bind))
  9272. BLOCK_VARS (gimple_bind_block (inner_bind)) = NULL_TREE;
  9273. }
  9274. if (gimple_omp_for_combined_into_p (stmt))
  9275. {
  9276. extract_omp_for_data (stmt, &fd, NULL);
  9277. fdp = &fd;
  9278. /* We need two temporaries with fd.loop.v type (istart/iend)
  9279. and then (fd.collapse - 1) temporaries with the same
  9280. type for count2 ... countN-1 vars if not constant. */
  9281. size_t count = 2;
  9282. tree type = fd.iter_type;
  9283. if (fd.collapse > 1
  9284. && TREE_CODE (fd.loop.n2) != INTEGER_CST)
  9285. count += fd.collapse - 1;
  9286. bool parallel_for = gimple_omp_for_kind (stmt) == GF_OMP_FOR_KIND_FOR;
  9287. tree outerc = NULL, *pc = gimple_omp_for_clauses_ptr (stmt);
  9288. tree clauses = *pc;
  9289. if (parallel_for)
  9290. outerc
  9291. = find_omp_clause (gimple_omp_parallel_clauses (ctx->outer->stmt),
  9292. OMP_CLAUSE__LOOPTEMP_);
  9293. for (i = 0; i < count; i++)
  9294. {
  9295. tree temp;
  9296. if (parallel_for)
  9297. {
  9298. gcc_assert (outerc);
  9299. temp = lookup_decl (OMP_CLAUSE_DECL (outerc), ctx->outer);
  9300. outerc = find_omp_clause (OMP_CLAUSE_CHAIN (outerc),
  9301. OMP_CLAUSE__LOOPTEMP_);
  9302. }
  9303. else
  9304. {
  9305. temp = create_tmp_var (type);
  9306. insert_decl_map (&ctx->outer->cb, temp, temp);
  9307. }
  9308. *pc = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE__LOOPTEMP_);
  9309. OMP_CLAUSE_DECL (*pc) = temp;
  9310. pc = &OMP_CLAUSE_CHAIN (*pc);
  9311. }
  9312. *pc = clauses;
  9313. }
  9314. /* The pre-body and input clauses go before the lowered GIMPLE_OMP_FOR. */
  9315. dlist = NULL;
  9316. body = NULL;
  9317. lower_rec_input_clauses (gimple_omp_for_clauses (stmt), &body, &dlist, ctx,
  9318. fdp);
  9319. gimple_seq_add_seq (&body, gimple_omp_for_pre_body (stmt));
  9320. lower_omp (gimple_omp_body_ptr (stmt), ctx);
  9321. /* Lower the header expressions. At this point, we can assume that
  9322. the header is of the form:
  9323. #pragma omp for (V = VAL1; V {<|>|<=|>=} VAL2; V = V [+-] VAL3)
  9324. We just need to make sure that VAL1, VAL2 and VAL3 are lowered
  9325. using the .omp_data_s mapping, if needed. */
  9326. for (i = 0; i < gimple_omp_for_collapse (stmt); i++)
  9327. {
  9328. rhs_p = gimple_omp_for_initial_ptr (stmt, i);
  9329. if (!is_gimple_min_invariant (*rhs_p))
  9330. *rhs_p = get_formal_tmp_var (*rhs_p, &body);
  9331. rhs_p = gimple_omp_for_final_ptr (stmt, i);
  9332. if (!is_gimple_min_invariant (*rhs_p))
  9333. *rhs_p = get_formal_tmp_var (*rhs_p, &body);
  9334. rhs_p = &TREE_OPERAND (gimple_omp_for_incr (stmt, i), 1);
  9335. if (!is_gimple_min_invariant (*rhs_p))
  9336. *rhs_p = get_formal_tmp_var (*rhs_p, &body);
  9337. }
  9338. /* Once lowered, extract the bounds and clauses. */
  9339. extract_omp_for_data (stmt, &fd, NULL);
  9340. lower_omp_for_lastprivate (&fd, &body, &dlist, ctx);
  9341. gimple_seq_add_stmt (&body, stmt);
  9342. gimple_seq_add_seq (&body, gimple_omp_body (stmt));
  9343. gimple_seq_add_stmt (&body, gimple_build_omp_continue (fd.loop.v,
  9344. fd.loop.v));
  9345. /* After the loop, add exit clauses. */
  9346. lower_reduction_clauses (gimple_omp_for_clauses (stmt), &body, ctx);
  9347. if (ctx->cancellable)
  9348. gimple_seq_add_stmt (&body, gimple_build_label (ctx->cancel_label));
  9349. gimple_seq_add_seq (&body, dlist);
  9350. body = maybe_catch_exception (body);
  9351. /* Region exit marker goes at the end of the loop body. */
  9352. gimple_seq_add_stmt (&body, gimple_build_omp_return (fd.have_nowait));
  9353. maybe_add_implicit_barrier_cancel (ctx, &body);
  9354. pop_gimplify_context (new_stmt);
  9355. gimple_bind_append_vars (new_stmt, ctx->block_vars);
  9356. BLOCK_VARS (block) = gimple_bind_vars (new_stmt);
  9357. if (BLOCK_VARS (block))
  9358. TREE_USED (block) = 1;
  9359. gimple_bind_set_body (new_stmt, body);
  9360. gimple_omp_set_body (stmt, NULL);
  9361. gimple_omp_for_set_pre_body (stmt, NULL);
  9362. }
  9363. /* Callback for walk_stmts. Check if the current statement only contains
  9364. GIMPLE_OMP_FOR or GIMPLE_OMP_SECTIONS. */
  9365. static tree
  9366. check_combined_parallel (gimple_stmt_iterator *gsi_p,
  9367. bool *handled_ops_p,
  9368. struct walk_stmt_info *wi)
  9369. {
  9370. int *info = (int *) wi->info;
  9371. gimple stmt = gsi_stmt (*gsi_p);
  9372. *handled_ops_p = true;
  9373. switch (gimple_code (stmt))
  9374. {
  9375. WALK_SUBSTMTS;
  9376. case GIMPLE_OMP_FOR:
  9377. case GIMPLE_OMP_SECTIONS:
  9378. *info = *info == 0 ? 1 : -1;
  9379. break;
  9380. default:
  9381. *info = -1;
  9382. break;
  9383. }
  9384. return NULL;
  9385. }
  9386. struct omp_taskcopy_context
  9387. {
  9388. /* This field must be at the beginning, as we do "inheritance": Some
  9389. callback functions for tree-inline.c (e.g., omp_copy_decl)
  9390. receive a copy_body_data pointer that is up-casted to an
  9391. omp_context pointer. */
  9392. copy_body_data cb;
  9393. omp_context *ctx;
  9394. };
  9395. static tree
  9396. task_copyfn_copy_decl (tree var, copy_body_data *cb)
  9397. {
  9398. struct omp_taskcopy_context *tcctx = (struct omp_taskcopy_context *) cb;
  9399. if (splay_tree_lookup (tcctx->ctx->sfield_map, (splay_tree_key) var))
  9400. return create_tmp_var (TREE_TYPE (var));
  9401. return var;
  9402. }
  9403. static tree
  9404. task_copyfn_remap_type (struct omp_taskcopy_context *tcctx, tree orig_type)
  9405. {
  9406. tree name, new_fields = NULL, type, f;
  9407. type = lang_hooks.types.make_type (RECORD_TYPE);
  9408. name = DECL_NAME (TYPE_NAME (orig_type));
  9409. name = build_decl (gimple_location (tcctx->ctx->stmt),
  9410. TYPE_DECL, name, type);
  9411. TYPE_NAME (type) = name;
  9412. for (f = TYPE_FIELDS (orig_type); f ; f = TREE_CHAIN (f))
  9413. {
  9414. tree new_f = copy_node (f);
  9415. DECL_CONTEXT (new_f) = type;
  9416. TREE_TYPE (new_f) = remap_type (TREE_TYPE (f), &tcctx->cb);
  9417. TREE_CHAIN (new_f) = new_fields;
  9418. walk_tree (&DECL_SIZE (new_f), copy_tree_body_r, &tcctx->cb, NULL);
  9419. walk_tree (&DECL_SIZE_UNIT (new_f), copy_tree_body_r, &tcctx->cb, NULL);
  9420. walk_tree (&DECL_FIELD_OFFSET (new_f), copy_tree_body_r,
  9421. &tcctx->cb, NULL);
  9422. new_fields = new_f;
  9423. tcctx->cb.decl_map->put (f, new_f);
  9424. }
  9425. TYPE_FIELDS (type) = nreverse (new_fields);
  9426. layout_type (type);
  9427. return type;
  9428. }
  9429. /* Create task copyfn. */
  9430. static void
  9431. create_task_copyfn (gomp_task *task_stmt, omp_context *ctx)
  9432. {
  9433. struct function *child_cfun;
  9434. tree child_fn, t, c, src, dst, f, sf, arg, sarg, decl;
  9435. tree record_type, srecord_type, bind, list;
  9436. bool record_needs_remap = false, srecord_needs_remap = false;
  9437. splay_tree_node n;
  9438. struct omp_taskcopy_context tcctx;
  9439. location_t loc = gimple_location (task_stmt);
  9440. child_fn = gimple_omp_task_copy_fn (task_stmt);
  9441. child_cfun = DECL_STRUCT_FUNCTION (child_fn);
  9442. gcc_assert (child_cfun->cfg == NULL);
  9443. DECL_SAVED_TREE (child_fn) = alloc_stmt_list ();
  9444. /* Reset DECL_CONTEXT on function arguments. */
  9445. for (t = DECL_ARGUMENTS (child_fn); t; t = DECL_CHAIN (t))
  9446. DECL_CONTEXT (t) = child_fn;
  9447. /* Populate the function. */
  9448. push_gimplify_context ();
  9449. push_cfun (child_cfun);
  9450. bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL);
  9451. TREE_SIDE_EFFECTS (bind) = 1;
  9452. list = NULL;
  9453. DECL_SAVED_TREE (child_fn) = bind;
  9454. DECL_SOURCE_LOCATION (child_fn) = gimple_location (task_stmt);
  9455. /* Remap src and dst argument types if needed. */
  9456. record_type = ctx->record_type;
  9457. srecord_type = ctx->srecord_type;
  9458. for (f = TYPE_FIELDS (record_type); f ; f = DECL_CHAIN (f))
  9459. if (variably_modified_type_p (TREE_TYPE (f), ctx->cb.src_fn))
  9460. {
  9461. record_needs_remap = true;
  9462. break;
  9463. }
  9464. for (f = TYPE_FIELDS (srecord_type); f ; f = DECL_CHAIN (f))
  9465. if (variably_modified_type_p (TREE_TYPE (f), ctx->cb.src_fn))
  9466. {
  9467. srecord_needs_remap = true;
  9468. break;
  9469. }
  9470. if (record_needs_remap || srecord_needs_remap)
  9471. {
  9472. memset (&tcctx, '\0', sizeof (tcctx));
  9473. tcctx.cb.src_fn = ctx->cb.src_fn;
  9474. tcctx.cb.dst_fn = child_fn;
  9475. tcctx.cb.src_node = cgraph_node::get (tcctx.cb.src_fn);
  9476. gcc_checking_assert (tcctx.cb.src_node);
  9477. tcctx.cb.dst_node = tcctx.cb.src_node;
  9478. tcctx.cb.src_cfun = ctx->cb.src_cfun;
  9479. tcctx.cb.copy_decl = task_copyfn_copy_decl;
  9480. tcctx.cb.eh_lp_nr = 0;
  9481. tcctx.cb.transform_call_graph_edges = CB_CGE_MOVE;
  9482. tcctx.cb.decl_map = new hash_map<tree, tree>;
  9483. tcctx.ctx = ctx;
  9484. if (record_needs_remap)
  9485. record_type = task_copyfn_remap_type (&tcctx, record_type);
  9486. if (srecord_needs_remap)
  9487. srecord_type = task_copyfn_remap_type (&tcctx, srecord_type);
  9488. }
  9489. else
  9490. tcctx.cb.decl_map = NULL;
  9491. arg = DECL_ARGUMENTS (child_fn);
  9492. TREE_TYPE (arg) = build_pointer_type (record_type);
  9493. sarg = DECL_CHAIN (arg);
  9494. TREE_TYPE (sarg) = build_pointer_type (srecord_type);
  9495. /* First pass: initialize temporaries used in record_type and srecord_type
  9496. sizes and field offsets. */
  9497. if (tcctx.cb.decl_map)
  9498. for (c = gimple_omp_task_clauses (task_stmt); c; c = OMP_CLAUSE_CHAIN (c))
  9499. if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE)
  9500. {
  9501. tree *p;
  9502. decl = OMP_CLAUSE_DECL (c);
  9503. p = tcctx.cb.decl_map->get (decl);
  9504. if (p == NULL)
  9505. continue;
  9506. n = splay_tree_lookup (ctx->sfield_map, (splay_tree_key) decl);
  9507. sf = (tree) n->value;
  9508. sf = *tcctx.cb.decl_map->get (sf);
  9509. src = build_simple_mem_ref_loc (loc, sarg);
  9510. src = omp_build_component_ref (src, sf);
  9511. t = build2 (MODIFY_EXPR, TREE_TYPE (*p), *p, src);
  9512. append_to_statement_list (t, &list);
  9513. }
  9514. /* Second pass: copy shared var pointers and copy construct non-VLA
  9515. firstprivate vars. */
  9516. for (c = gimple_omp_task_clauses (task_stmt); c; c = OMP_CLAUSE_CHAIN (c))
  9517. switch (OMP_CLAUSE_CODE (c))
  9518. {
  9519. case OMP_CLAUSE_SHARED:
  9520. decl = OMP_CLAUSE_DECL (c);
  9521. n = splay_tree_lookup (ctx->field_map, (splay_tree_key) decl);
  9522. if (n == NULL)
  9523. break;
  9524. f = (tree) n->value;
  9525. if (tcctx.cb.decl_map)
  9526. f = *tcctx.cb.decl_map->get (f);
  9527. n = splay_tree_lookup (ctx->sfield_map, (splay_tree_key) decl);
  9528. sf = (tree) n->value;
  9529. if (tcctx.cb.decl_map)
  9530. sf = *tcctx.cb.decl_map->get (sf);
  9531. src = build_simple_mem_ref_loc (loc, sarg);
  9532. src = omp_build_component_ref (src, sf);
  9533. dst = build_simple_mem_ref_loc (loc, arg);
  9534. dst = omp_build_component_ref (dst, f);
  9535. t = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
  9536. append_to_statement_list (t, &list);
  9537. break;
  9538. case OMP_CLAUSE_FIRSTPRIVATE:
  9539. decl = OMP_CLAUSE_DECL (c);
  9540. if (is_variable_sized (decl))
  9541. break;
  9542. n = splay_tree_lookup (ctx->field_map, (splay_tree_key) decl);
  9543. if (n == NULL)
  9544. break;
  9545. f = (tree) n->value;
  9546. if (tcctx.cb.decl_map)
  9547. f = *tcctx.cb.decl_map->get (f);
  9548. n = splay_tree_lookup (ctx->sfield_map, (splay_tree_key) decl);
  9549. if (n != NULL)
  9550. {
  9551. sf = (tree) n->value;
  9552. if (tcctx.cb.decl_map)
  9553. sf = *tcctx.cb.decl_map->get (sf);
  9554. src = build_simple_mem_ref_loc (loc, sarg);
  9555. src = omp_build_component_ref (src, sf);
  9556. if (use_pointer_for_field (decl, NULL) || is_reference (decl))
  9557. src = build_simple_mem_ref_loc (loc, src);
  9558. }
  9559. else
  9560. src = decl;
  9561. dst = build_simple_mem_ref_loc (loc, arg);
  9562. dst = omp_build_component_ref (dst, f);
  9563. t = lang_hooks.decls.omp_clause_copy_ctor (c, dst, src);
  9564. append_to_statement_list (t, &list);
  9565. break;
  9566. case OMP_CLAUSE_PRIVATE:
  9567. if (! OMP_CLAUSE_PRIVATE_OUTER_REF (c))
  9568. break;
  9569. decl = OMP_CLAUSE_DECL (c);
  9570. n = splay_tree_lookup (ctx->field_map, (splay_tree_key) decl);
  9571. f = (tree) n->value;
  9572. if (tcctx.cb.decl_map)
  9573. f = *tcctx.cb.decl_map->get (f);
  9574. n = splay_tree_lookup (ctx->sfield_map, (splay_tree_key) decl);
  9575. if (n != NULL)
  9576. {
  9577. sf = (tree) n->value;
  9578. if (tcctx.cb.decl_map)
  9579. sf = *tcctx.cb.decl_map->get (sf);
  9580. src = build_simple_mem_ref_loc (loc, sarg);
  9581. src = omp_build_component_ref (src, sf);
  9582. if (use_pointer_for_field (decl, NULL))
  9583. src = build_simple_mem_ref_loc (loc, src);
  9584. }
  9585. else
  9586. src = decl;
  9587. dst = build_simple_mem_ref_loc (loc, arg);
  9588. dst = omp_build_component_ref (dst, f);
  9589. t = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
  9590. append_to_statement_list (t, &list);
  9591. break;
  9592. default:
  9593. break;
  9594. }
  9595. /* Last pass: handle VLA firstprivates. */
  9596. if (tcctx.cb.decl_map)
  9597. for (c = gimple_omp_task_clauses (task_stmt); c; c = OMP_CLAUSE_CHAIN (c))
  9598. if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE)
  9599. {
  9600. tree ind, ptr, df;
  9601. decl = OMP_CLAUSE_DECL (c);
  9602. if (!is_variable_sized (decl))
  9603. continue;
  9604. n = splay_tree_lookup (ctx->field_map, (splay_tree_key) decl);
  9605. if (n == NULL)
  9606. continue;
  9607. f = (tree) n->value;
  9608. f = *tcctx.cb.decl_map->get (f);
  9609. gcc_assert (DECL_HAS_VALUE_EXPR_P (decl));
  9610. ind = DECL_VALUE_EXPR (decl);
  9611. gcc_assert (TREE_CODE (ind) == INDIRECT_REF);
  9612. gcc_assert (DECL_P (TREE_OPERAND (ind, 0)));
  9613. n = splay_tree_lookup (ctx->sfield_map,
  9614. (splay_tree_key) TREE_OPERAND (ind, 0));
  9615. sf = (tree) n->value;
  9616. sf = *tcctx.cb.decl_map->get (sf);
  9617. src = build_simple_mem_ref_loc (loc, sarg);
  9618. src = omp_build_component_ref (src, sf);
  9619. src = build_simple_mem_ref_loc (loc, src);
  9620. dst = build_simple_mem_ref_loc (loc, arg);
  9621. dst = omp_build_component_ref (dst, f);
  9622. t = lang_hooks.decls.omp_clause_copy_ctor (c, dst, src);
  9623. append_to_statement_list (t, &list);
  9624. n = splay_tree_lookup (ctx->field_map,
  9625. (splay_tree_key) TREE_OPERAND (ind, 0));
  9626. df = (tree) n->value;
  9627. df = *tcctx.cb.decl_map->get (df);
  9628. ptr = build_simple_mem_ref_loc (loc, arg);
  9629. ptr = omp_build_component_ref (ptr, df);
  9630. t = build2 (MODIFY_EXPR, TREE_TYPE (ptr), ptr,
  9631. build_fold_addr_expr_loc (loc, dst));
  9632. append_to_statement_list (t, &list);
  9633. }
  9634. t = build1 (RETURN_EXPR, void_type_node, NULL);
  9635. append_to_statement_list (t, &list);
  9636. if (tcctx.cb.decl_map)
  9637. delete tcctx.cb.decl_map;
  9638. pop_gimplify_context (NULL);
  9639. BIND_EXPR_BODY (bind) = list;
  9640. pop_cfun ();
  9641. }
  9642. static void
  9643. lower_depend_clauses (gimple stmt, gimple_seq *iseq, gimple_seq *oseq)
  9644. {
  9645. tree c, clauses;
  9646. gimple g;
  9647. size_t n_in = 0, n_out = 0, idx = 2, i;
  9648. clauses = find_omp_clause (gimple_omp_task_clauses (stmt),
  9649. OMP_CLAUSE_DEPEND);
  9650. gcc_assert (clauses);
  9651. for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
  9652. if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND)
  9653. switch (OMP_CLAUSE_DEPEND_KIND (c))
  9654. {
  9655. case OMP_CLAUSE_DEPEND_IN:
  9656. n_in++;
  9657. break;
  9658. case OMP_CLAUSE_DEPEND_OUT:
  9659. case OMP_CLAUSE_DEPEND_INOUT:
  9660. n_out++;
  9661. break;
  9662. default:
  9663. gcc_unreachable ();
  9664. }
  9665. tree type = build_array_type_nelts (ptr_type_node, n_in + n_out + 2);
  9666. tree array = create_tmp_var (type);
  9667. tree r = build4 (ARRAY_REF, ptr_type_node, array, size_int (0), NULL_TREE,
  9668. NULL_TREE);
  9669. g = gimple_build_assign (r, build_int_cst (ptr_type_node, n_in + n_out));
  9670. gimple_seq_add_stmt (iseq, g);
  9671. r = build4 (ARRAY_REF, ptr_type_node, array, size_int (1), NULL_TREE,
  9672. NULL_TREE);
  9673. g = gimple_build_assign (r, build_int_cst (ptr_type_node, n_out));
  9674. gimple_seq_add_stmt (iseq, g);
  9675. for (i = 0; i < 2; i++)
  9676. {
  9677. if ((i ? n_in : n_out) == 0)
  9678. continue;
  9679. for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
  9680. if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
  9681. && ((OMP_CLAUSE_DEPEND_KIND (c) != OMP_CLAUSE_DEPEND_IN) ^ i))
  9682. {
  9683. tree t = OMP_CLAUSE_DECL (c);
  9684. t = fold_convert (ptr_type_node, t);
  9685. gimplify_expr (&t, iseq, NULL, is_gimple_val, fb_rvalue);
  9686. r = build4 (ARRAY_REF, ptr_type_node, array, size_int (idx++),
  9687. NULL_TREE, NULL_TREE);
  9688. g = gimple_build_assign (r, t);
  9689. gimple_seq_add_stmt (iseq, g);
  9690. }
  9691. }
  9692. tree *p = gimple_omp_task_clauses_ptr (stmt);
  9693. c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_DEPEND);
  9694. OMP_CLAUSE_DECL (c) = build_fold_addr_expr (array);
  9695. OMP_CLAUSE_CHAIN (c) = *p;
  9696. *p = c;
  9697. tree clobber = build_constructor (type, NULL);
  9698. TREE_THIS_VOLATILE (clobber) = 1;
  9699. g = gimple_build_assign (array, clobber);
  9700. gimple_seq_add_stmt (oseq, g);
  9701. }
  9702. /* Lower the OpenMP parallel or task directive in the current statement
  9703. in GSI_P. CTX holds context information for the directive. */
  9704. static void
  9705. lower_omp_taskreg (gimple_stmt_iterator *gsi_p, omp_context *ctx)
  9706. {
  9707. tree clauses;
  9708. tree child_fn, t;
  9709. gimple stmt = gsi_stmt (*gsi_p);
  9710. gbind *par_bind, *bind, *dep_bind = NULL;
  9711. gimple_seq par_body, olist, ilist, par_olist, par_rlist, par_ilist, new_body;
  9712. location_t loc = gimple_location (stmt);
  9713. clauses = gimple_omp_taskreg_clauses (stmt);
  9714. par_bind
  9715. = as_a <gbind *> (gimple_seq_first_stmt (gimple_omp_body (stmt)));
  9716. par_body = gimple_bind_body (par_bind);
  9717. child_fn = ctx->cb.dst_fn;
  9718. if (gimple_code (stmt) == GIMPLE_OMP_PARALLEL
  9719. && !gimple_omp_parallel_combined_p (stmt))
  9720. {
  9721. struct walk_stmt_info wi;
  9722. int ws_num = 0;
  9723. memset (&wi, 0, sizeof (wi));
  9724. wi.info = &ws_num;
  9725. wi.val_only = true;
  9726. walk_gimple_seq (par_body, check_combined_parallel, NULL, &wi);
  9727. if (ws_num == 1)
  9728. gimple_omp_parallel_set_combined_p (stmt, true);
  9729. }
  9730. gimple_seq dep_ilist = NULL;
  9731. gimple_seq dep_olist = NULL;
  9732. if (gimple_code (stmt) == GIMPLE_OMP_TASK
  9733. && find_omp_clause (clauses, OMP_CLAUSE_DEPEND))
  9734. {
  9735. push_gimplify_context ();
  9736. dep_bind = gimple_build_bind (NULL, NULL, make_node (BLOCK));
  9737. lower_depend_clauses (stmt, &dep_ilist, &dep_olist);
  9738. }
  9739. if (ctx->srecord_type)
  9740. create_task_copyfn (as_a <gomp_task *> (stmt), ctx);
  9741. push_gimplify_context ();
  9742. par_olist = NULL;
  9743. par_ilist = NULL;
  9744. par_rlist = NULL;
  9745. lower_rec_input_clauses (clauses, &par_ilist, &par_olist, ctx, NULL);
  9746. lower_omp (&par_body, ctx);
  9747. if (gimple_code (stmt) == GIMPLE_OMP_PARALLEL)
  9748. lower_reduction_clauses (clauses, &par_rlist, ctx);
  9749. /* Declare all the variables created by mapping and the variables
  9750. declared in the scope of the parallel body. */
  9751. record_vars_into (ctx->block_vars, child_fn);
  9752. record_vars_into (gimple_bind_vars (par_bind), child_fn);
  9753. if (ctx->record_type)
  9754. {
  9755. ctx->sender_decl
  9756. = create_tmp_var (ctx->srecord_type ? ctx->srecord_type
  9757. : ctx->record_type, ".omp_data_o");
  9758. DECL_NAMELESS (ctx->sender_decl) = 1;
  9759. TREE_ADDRESSABLE (ctx->sender_decl) = 1;
  9760. gimple_omp_taskreg_set_data_arg (stmt, ctx->sender_decl);
  9761. }
  9762. olist = NULL;
  9763. ilist = NULL;
  9764. lower_send_clauses (clauses, &ilist, &olist, ctx);
  9765. lower_send_shared_vars (&ilist, &olist, ctx);
  9766. if (ctx->record_type)
  9767. {
  9768. tree clobber = build_constructor (TREE_TYPE (ctx->sender_decl), NULL);
  9769. TREE_THIS_VOLATILE (clobber) = 1;
  9770. gimple_seq_add_stmt (&olist, gimple_build_assign (ctx->sender_decl,
  9771. clobber));
  9772. }
  9773. /* Once all the expansions are done, sequence all the different
  9774. fragments inside gimple_omp_body. */
  9775. new_body = NULL;
  9776. if (ctx->record_type)
  9777. {
  9778. t = build_fold_addr_expr_loc (loc, ctx->sender_decl);
  9779. /* fixup_child_record_type might have changed receiver_decl's type. */
  9780. t = fold_convert_loc (loc, TREE_TYPE (ctx->receiver_decl), t);
  9781. gimple_seq_add_stmt (&new_body,
  9782. gimple_build_assign (ctx->receiver_decl, t));
  9783. }
  9784. gimple_seq_add_seq (&new_body, par_ilist);
  9785. gimple_seq_add_seq (&new_body, par_body);
  9786. gimple_seq_add_seq (&new_body, par_rlist);
  9787. if (ctx->cancellable)
  9788. gimple_seq_add_stmt (&new_body, gimple_build_label (ctx->cancel_label));
  9789. gimple_seq_add_seq (&new_body, par_olist);
  9790. new_body = maybe_catch_exception (new_body);
  9791. if (gimple_code (stmt) == GIMPLE_OMP_TASK)
  9792. gimple_seq_add_stmt (&new_body,
  9793. gimple_build_omp_continue (integer_zero_node,
  9794. integer_zero_node));
  9795. gimple_seq_add_stmt (&new_body, gimple_build_omp_return (false));
  9796. gimple_omp_set_body (stmt, new_body);
  9797. bind = gimple_build_bind (NULL, NULL, gimple_bind_block (par_bind));
  9798. gsi_replace (gsi_p, dep_bind ? dep_bind : bind, true);
  9799. gimple_bind_add_seq (bind, ilist);
  9800. gimple_bind_add_stmt (bind, stmt);
  9801. gimple_bind_add_seq (bind, olist);
  9802. pop_gimplify_context (NULL);
  9803. if (dep_bind)
  9804. {
  9805. gimple_bind_add_seq (dep_bind, dep_ilist);
  9806. gimple_bind_add_stmt (dep_bind, bind);
  9807. gimple_bind_add_seq (dep_bind, dep_olist);
  9808. pop_gimplify_context (dep_bind);
  9809. }
  9810. }
  9811. /* Lower the GIMPLE_OMP_TARGET in the current statement
  9812. in GSI_P. CTX holds context information for the directive. */
  9813. static void
  9814. lower_omp_target (gimple_stmt_iterator *gsi_p, omp_context *ctx)
  9815. {
  9816. tree clauses;
  9817. tree child_fn, t, c;
  9818. gomp_target *stmt = as_a <gomp_target *> (gsi_stmt (*gsi_p));
  9819. gbind *tgt_bind, *bind;
  9820. gimple_seq tgt_body, olist, ilist, orlist, irlist, new_body;
  9821. location_t loc = gimple_location (stmt);
  9822. bool offloaded, data_region;
  9823. unsigned int map_cnt = 0;
  9824. offloaded = is_gimple_omp_offloaded (stmt);
  9825. switch (gimple_omp_target_kind (stmt))
  9826. {
  9827. case GF_OMP_TARGET_KIND_REGION:
  9828. case GF_OMP_TARGET_KIND_UPDATE:
  9829. case GF_OMP_TARGET_KIND_OACC_PARALLEL:
  9830. case GF_OMP_TARGET_KIND_OACC_KERNELS:
  9831. case GF_OMP_TARGET_KIND_OACC_UPDATE:
  9832. case GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA:
  9833. data_region = false;
  9834. break;
  9835. case GF_OMP_TARGET_KIND_DATA:
  9836. case GF_OMP_TARGET_KIND_OACC_DATA:
  9837. data_region = true;
  9838. break;
  9839. default:
  9840. gcc_unreachable ();
  9841. }
  9842. clauses = gimple_omp_target_clauses (stmt);
  9843. tgt_bind = NULL;
  9844. tgt_body = NULL;
  9845. if (offloaded)
  9846. {
  9847. tgt_bind = gimple_seq_first_stmt_as_a_bind (gimple_omp_body (stmt));
  9848. tgt_body = gimple_bind_body (tgt_bind);
  9849. }
  9850. else if (data_region)
  9851. tgt_body = gimple_omp_body (stmt);
  9852. child_fn = ctx->cb.dst_fn;
  9853. push_gimplify_context ();
  9854. irlist = NULL;
  9855. orlist = NULL;
  9856. if (offloaded
  9857. && is_gimple_omp_oacc (stmt))
  9858. oacc_process_reduction_data (&tgt_body, &irlist, &orlist, ctx);
  9859. for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
  9860. switch (OMP_CLAUSE_CODE (c))
  9861. {
  9862. tree var, x;
  9863. default:
  9864. break;
  9865. case OMP_CLAUSE_MAP:
  9866. #ifdef ENABLE_CHECKING
  9867. /* First check what we're prepared to handle in the following. */
  9868. switch (OMP_CLAUSE_MAP_KIND (c))
  9869. {
  9870. case GOMP_MAP_ALLOC:
  9871. case GOMP_MAP_TO:
  9872. case GOMP_MAP_FROM:
  9873. case GOMP_MAP_TOFROM:
  9874. case GOMP_MAP_POINTER:
  9875. case GOMP_MAP_TO_PSET:
  9876. break;
  9877. case GOMP_MAP_FORCE_ALLOC:
  9878. case GOMP_MAP_FORCE_TO:
  9879. case GOMP_MAP_FORCE_FROM:
  9880. case GOMP_MAP_FORCE_TOFROM:
  9881. case GOMP_MAP_FORCE_PRESENT:
  9882. case GOMP_MAP_FORCE_DEALLOC:
  9883. case GOMP_MAP_FORCE_DEVICEPTR:
  9884. gcc_assert (is_gimple_omp_oacc (stmt));
  9885. break;
  9886. default:
  9887. gcc_unreachable ();
  9888. }
  9889. #endif
  9890. /* FALLTHRU */
  9891. case OMP_CLAUSE_TO:
  9892. case OMP_CLAUSE_FROM:
  9893. var = OMP_CLAUSE_DECL (c);
  9894. if (!DECL_P (var))
  9895. {
  9896. if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_MAP
  9897. || !OMP_CLAUSE_MAP_ZERO_BIAS_ARRAY_SECTION (c))
  9898. map_cnt++;
  9899. continue;
  9900. }
  9901. if (DECL_SIZE (var)
  9902. && TREE_CODE (DECL_SIZE (var)) != INTEGER_CST)
  9903. {
  9904. tree var2 = DECL_VALUE_EXPR (var);
  9905. gcc_assert (TREE_CODE (var2) == INDIRECT_REF);
  9906. var2 = TREE_OPERAND (var2, 0);
  9907. gcc_assert (DECL_P (var2));
  9908. var = var2;
  9909. }
  9910. if (!maybe_lookup_field (var, ctx))
  9911. continue;
  9912. if (offloaded)
  9913. {
  9914. x = build_receiver_ref (var, true, ctx);
  9915. tree new_var = lookup_decl (var, ctx);
  9916. if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POINTER
  9917. && !OMP_CLAUSE_MAP_ZERO_BIAS_ARRAY_SECTION (c)
  9918. && TREE_CODE (TREE_TYPE (var)) == ARRAY_TYPE)
  9919. x = build_simple_mem_ref (x);
  9920. SET_DECL_VALUE_EXPR (new_var, x);
  9921. DECL_HAS_VALUE_EXPR_P (new_var) = 1;
  9922. }
  9923. map_cnt++;
  9924. }
  9925. if (offloaded)
  9926. {
  9927. target_nesting_level++;
  9928. lower_omp (&tgt_body, ctx);
  9929. target_nesting_level--;
  9930. }
  9931. else if (data_region)
  9932. lower_omp (&tgt_body, ctx);
  9933. if (offloaded)
  9934. {
  9935. /* Declare all the variables created by mapping and the variables
  9936. declared in the scope of the target body. */
  9937. record_vars_into (ctx->block_vars, child_fn);
  9938. record_vars_into (gimple_bind_vars (tgt_bind), child_fn);
  9939. }
  9940. olist = NULL;
  9941. ilist = NULL;
  9942. if (ctx->record_type)
  9943. {
  9944. ctx->sender_decl
  9945. = create_tmp_var (ctx->record_type, ".omp_data_arr");
  9946. DECL_NAMELESS (ctx->sender_decl) = 1;
  9947. TREE_ADDRESSABLE (ctx->sender_decl) = 1;
  9948. t = make_tree_vec (3);
  9949. TREE_VEC_ELT (t, 0) = ctx->sender_decl;
  9950. TREE_VEC_ELT (t, 1)
  9951. = create_tmp_var (build_array_type_nelts (size_type_node, map_cnt),
  9952. ".omp_data_sizes");
  9953. DECL_NAMELESS (TREE_VEC_ELT (t, 1)) = 1;
  9954. TREE_ADDRESSABLE (TREE_VEC_ELT (t, 1)) = 1;
  9955. TREE_STATIC (TREE_VEC_ELT (t, 1)) = 1;
  9956. tree tkind_type;
  9957. int talign_shift;
  9958. if (is_gimple_omp_oacc (stmt))
  9959. {
  9960. tkind_type = short_unsigned_type_node;
  9961. talign_shift = 8;
  9962. }
  9963. else
  9964. {
  9965. tkind_type = unsigned_char_type_node;
  9966. talign_shift = 3;
  9967. }
  9968. TREE_VEC_ELT (t, 2)
  9969. = create_tmp_var (build_array_type_nelts (tkind_type, map_cnt),
  9970. ".omp_data_kinds");
  9971. DECL_NAMELESS (TREE_VEC_ELT (t, 2)) = 1;
  9972. TREE_ADDRESSABLE (TREE_VEC_ELT (t, 2)) = 1;
  9973. TREE_STATIC (TREE_VEC_ELT (t, 2)) = 1;
  9974. gimple_omp_target_set_data_arg (stmt, t);
  9975. vec<constructor_elt, va_gc> *vsize;
  9976. vec<constructor_elt, va_gc> *vkind;
  9977. vec_alloc (vsize, map_cnt);
  9978. vec_alloc (vkind, map_cnt);
  9979. unsigned int map_idx = 0;
  9980. for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
  9981. switch (OMP_CLAUSE_CODE (c))
  9982. {
  9983. tree ovar, nc;
  9984. default:
  9985. break;
  9986. case OMP_CLAUSE_MAP:
  9987. case OMP_CLAUSE_TO:
  9988. case OMP_CLAUSE_FROM:
  9989. nc = c;
  9990. ovar = OMP_CLAUSE_DECL (c);
  9991. if (!DECL_P (ovar))
  9992. {
  9993. if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
  9994. && OMP_CLAUSE_MAP_ZERO_BIAS_ARRAY_SECTION (c))
  9995. {
  9996. gcc_checking_assert (OMP_CLAUSE_DECL (OMP_CLAUSE_CHAIN (c))
  9997. == get_base_address (ovar));
  9998. nc = OMP_CLAUSE_CHAIN (c);
  9999. ovar = OMP_CLAUSE_DECL (nc);
  10000. }
  10001. else
  10002. {
  10003. tree x = build_sender_ref (ovar, ctx);
  10004. tree v
  10005. = build_fold_addr_expr_with_type (ovar, ptr_type_node);
  10006. gimplify_assign (x, v, &ilist);
  10007. nc = NULL_TREE;
  10008. }
  10009. }
  10010. else
  10011. {
  10012. if (DECL_SIZE (ovar)
  10013. && TREE_CODE (DECL_SIZE (ovar)) != INTEGER_CST)
  10014. {
  10015. tree ovar2 = DECL_VALUE_EXPR (ovar);
  10016. gcc_assert (TREE_CODE (ovar2) == INDIRECT_REF);
  10017. ovar2 = TREE_OPERAND (ovar2, 0);
  10018. gcc_assert (DECL_P (ovar2));
  10019. ovar = ovar2;
  10020. }
  10021. if (!maybe_lookup_field (ovar, ctx))
  10022. continue;
  10023. }
  10024. unsigned int talign = TYPE_ALIGN_UNIT (TREE_TYPE (ovar));
  10025. if (DECL_P (ovar) && DECL_ALIGN_UNIT (ovar) > talign)
  10026. talign = DECL_ALIGN_UNIT (ovar);
  10027. if (nc)
  10028. {
  10029. tree var = lookup_decl_in_outer_ctx (ovar, ctx);
  10030. tree x = build_sender_ref (ovar, ctx);
  10031. if (maybe_lookup_oacc_reduction (var, ctx))
  10032. {
  10033. gcc_checking_assert (offloaded
  10034. && is_gimple_omp_oacc (stmt));
  10035. gimplify_assign (x, var, &ilist);
  10036. }
  10037. else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
  10038. && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POINTER
  10039. && !OMP_CLAUSE_MAP_ZERO_BIAS_ARRAY_SECTION (c)
  10040. && TREE_CODE (TREE_TYPE (ovar)) == ARRAY_TYPE)
  10041. {
  10042. gcc_assert (offloaded);
  10043. tree avar
  10044. = create_tmp_var (TREE_TYPE (TREE_TYPE (x)));
  10045. mark_addressable (avar);
  10046. gimplify_assign (avar, build_fold_addr_expr (var), &ilist);
  10047. talign = DECL_ALIGN_UNIT (avar);
  10048. avar = build_fold_addr_expr (avar);
  10049. gimplify_assign (x, avar, &ilist);
  10050. }
  10051. else if (is_gimple_reg (var))
  10052. {
  10053. gcc_assert (offloaded);
  10054. tree avar = create_tmp_var (TREE_TYPE (var));
  10055. mark_addressable (avar);
  10056. enum gomp_map_kind map_kind = OMP_CLAUSE_MAP_KIND (c);
  10057. if (GOMP_MAP_COPY_TO_P (map_kind)
  10058. || map_kind == GOMP_MAP_POINTER
  10059. || map_kind == GOMP_MAP_TO_PSET
  10060. || map_kind == GOMP_MAP_FORCE_DEVICEPTR)
  10061. gimplify_assign (avar, var, &ilist);
  10062. avar = build_fold_addr_expr (avar);
  10063. gimplify_assign (x, avar, &ilist);
  10064. if ((GOMP_MAP_COPY_FROM_P (map_kind)
  10065. || map_kind == GOMP_MAP_FORCE_DEVICEPTR)
  10066. && !TYPE_READONLY (TREE_TYPE (var)))
  10067. {
  10068. x = build_sender_ref (ovar, ctx);
  10069. x = build_simple_mem_ref (x);
  10070. gimplify_assign (var, x, &olist);
  10071. }
  10072. }
  10073. else
  10074. {
  10075. var = build_fold_addr_expr (var);
  10076. gimplify_assign (x, var, &ilist);
  10077. }
  10078. }
  10079. tree s = OMP_CLAUSE_SIZE (c);
  10080. if (s == NULL_TREE)
  10081. s = TYPE_SIZE_UNIT (TREE_TYPE (ovar));
  10082. s = fold_convert (size_type_node, s);
  10083. tree purpose = size_int (map_idx++);
  10084. CONSTRUCTOR_APPEND_ELT (vsize, purpose, s);
  10085. if (TREE_CODE (s) != INTEGER_CST)
  10086. TREE_STATIC (TREE_VEC_ELT (t, 1)) = 0;
  10087. unsigned HOST_WIDE_INT tkind;
  10088. switch (OMP_CLAUSE_CODE (c))
  10089. {
  10090. case OMP_CLAUSE_MAP:
  10091. tkind = OMP_CLAUSE_MAP_KIND (c);
  10092. break;
  10093. case OMP_CLAUSE_TO:
  10094. tkind = GOMP_MAP_TO;
  10095. break;
  10096. case OMP_CLAUSE_FROM:
  10097. tkind = GOMP_MAP_FROM;
  10098. break;
  10099. default:
  10100. gcc_unreachable ();
  10101. }
  10102. gcc_checking_assert (tkind
  10103. < (HOST_WIDE_INT_C (1U) << talign_shift));
  10104. talign = ceil_log2 (talign);
  10105. tkind |= talign << talign_shift;
  10106. gcc_checking_assert (tkind
  10107. <= tree_to_uhwi (TYPE_MAX_VALUE (tkind_type)));
  10108. CONSTRUCTOR_APPEND_ELT (vkind, purpose,
  10109. build_int_cstu (tkind_type, tkind));
  10110. if (nc && nc != c)
  10111. c = nc;
  10112. }
  10113. gcc_assert (map_idx == map_cnt);
  10114. DECL_INITIAL (TREE_VEC_ELT (t, 1))
  10115. = build_constructor (TREE_TYPE (TREE_VEC_ELT (t, 1)), vsize);
  10116. DECL_INITIAL (TREE_VEC_ELT (t, 2))
  10117. = build_constructor (TREE_TYPE (TREE_VEC_ELT (t, 2)), vkind);
  10118. if (!TREE_STATIC (TREE_VEC_ELT (t, 1)))
  10119. {
  10120. gimple_seq initlist = NULL;
  10121. force_gimple_operand (build1 (DECL_EXPR, void_type_node,
  10122. TREE_VEC_ELT (t, 1)),
  10123. &initlist, true, NULL_TREE);
  10124. gimple_seq_add_seq (&ilist, initlist);
  10125. tree clobber = build_constructor (TREE_TYPE (TREE_VEC_ELT (t, 1)),
  10126. NULL);
  10127. TREE_THIS_VOLATILE (clobber) = 1;
  10128. gimple_seq_add_stmt (&olist,
  10129. gimple_build_assign (TREE_VEC_ELT (t, 1),
  10130. clobber));
  10131. }
  10132. tree clobber = build_constructor (ctx->record_type, NULL);
  10133. TREE_THIS_VOLATILE (clobber) = 1;
  10134. gimple_seq_add_stmt (&olist, gimple_build_assign (ctx->sender_decl,
  10135. clobber));
  10136. }
  10137. /* Once all the expansions are done, sequence all the different
  10138. fragments inside gimple_omp_body. */
  10139. new_body = NULL;
  10140. if (offloaded
  10141. && ctx->record_type)
  10142. {
  10143. t = build_fold_addr_expr_loc (loc, ctx->sender_decl);
  10144. /* fixup_child_record_type might have changed receiver_decl's type. */
  10145. t = fold_convert_loc (loc, TREE_TYPE (ctx->receiver_decl), t);
  10146. gimple_seq_add_stmt (&new_body,
  10147. gimple_build_assign (ctx->receiver_decl, t));
  10148. }
  10149. if (offloaded)
  10150. {
  10151. gimple_seq_add_seq (&new_body, tgt_body);
  10152. new_body = maybe_catch_exception (new_body);
  10153. }
  10154. else if (data_region)
  10155. new_body = tgt_body;
  10156. if (offloaded || data_region)
  10157. {
  10158. gimple_seq_add_stmt (&new_body, gimple_build_omp_return (false));
  10159. gimple_omp_set_body (stmt, new_body);
  10160. }
  10161. bind = gimple_build_bind (NULL, NULL,
  10162. tgt_bind ? gimple_bind_block (tgt_bind)
  10163. : NULL_TREE);
  10164. gsi_replace (gsi_p, bind, true);
  10165. gimple_bind_add_seq (bind, irlist);
  10166. gimple_bind_add_seq (bind, ilist);
  10167. gimple_bind_add_stmt (bind, stmt);
  10168. gimple_bind_add_seq (bind, olist);
  10169. gimple_bind_add_seq (bind, orlist);
  10170. pop_gimplify_context (NULL);
  10171. }
  10172. /* Expand code for an OpenMP teams directive. */
  10173. static void
  10174. lower_omp_teams (gimple_stmt_iterator *gsi_p, omp_context *ctx)
  10175. {
  10176. gomp_teams *teams_stmt = as_a <gomp_teams *> (gsi_stmt (*gsi_p));
  10177. push_gimplify_context ();
  10178. tree block = make_node (BLOCK);
  10179. gbind *bind = gimple_build_bind (NULL, NULL, block);
  10180. gsi_replace (gsi_p, bind, true);
  10181. gimple_seq bind_body = NULL;
  10182. gimple_seq dlist = NULL;
  10183. gimple_seq olist = NULL;
  10184. tree num_teams = find_omp_clause (gimple_omp_teams_clauses (teams_stmt),
  10185. OMP_CLAUSE_NUM_TEAMS);
  10186. if (num_teams == NULL_TREE)
  10187. num_teams = build_int_cst (unsigned_type_node, 0);
  10188. else
  10189. {
  10190. num_teams = OMP_CLAUSE_NUM_TEAMS_EXPR (num_teams);
  10191. num_teams = fold_convert (unsigned_type_node, num_teams);
  10192. gimplify_expr (&num_teams, &bind_body, NULL, is_gimple_val, fb_rvalue);
  10193. }
  10194. tree thread_limit = find_omp_clause (gimple_omp_teams_clauses (teams_stmt),
  10195. OMP_CLAUSE_THREAD_LIMIT);
  10196. if (thread_limit == NULL_TREE)
  10197. thread_limit = build_int_cst (unsigned_type_node, 0);
  10198. else
  10199. {
  10200. thread_limit = OMP_CLAUSE_THREAD_LIMIT_EXPR (thread_limit);
  10201. thread_limit = fold_convert (unsigned_type_node, thread_limit);
  10202. gimplify_expr (&thread_limit, &bind_body, NULL, is_gimple_val,
  10203. fb_rvalue);
  10204. }
  10205. lower_rec_input_clauses (gimple_omp_teams_clauses (teams_stmt),
  10206. &bind_body, &dlist, ctx, NULL);
  10207. lower_omp (gimple_omp_body_ptr (teams_stmt), ctx);
  10208. lower_reduction_clauses (gimple_omp_teams_clauses (teams_stmt), &olist, ctx);
  10209. gimple_seq_add_stmt (&bind_body, teams_stmt);
  10210. location_t loc = gimple_location (teams_stmt);
  10211. tree decl = builtin_decl_explicit (BUILT_IN_GOMP_TEAMS);
  10212. gimple call = gimple_build_call (decl, 2, num_teams, thread_limit);
  10213. gimple_set_location (call, loc);
  10214. gimple_seq_add_stmt (&bind_body, call);
  10215. gimple_seq_add_seq (&bind_body, gimple_omp_body (teams_stmt));
  10216. gimple_omp_set_body (teams_stmt, NULL);
  10217. gimple_seq_add_seq (&bind_body, olist);
  10218. gimple_seq_add_seq (&bind_body, dlist);
  10219. gimple_seq_add_stmt (&bind_body, gimple_build_omp_return (true));
  10220. gimple_bind_set_body (bind, bind_body);
  10221. pop_gimplify_context (bind);
  10222. gimple_bind_append_vars (bind, ctx->block_vars);
  10223. BLOCK_VARS (block) = ctx->block_vars;
  10224. if (BLOCK_VARS (block))
  10225. TREE_USED (block) = 1;
  10226. }
  10227. /* Callback for lower_omp_1. Return non-NULL if *tp needs to be
  10228. regimplified. If DATA is non-NULL, lower_omp_1 is outside
  10229. of OMP context, but with task_shared_vars set. */
  10230. static tree
  10231. lower_omp_regimplify_p (tree *tp, int *walk_subtrees,
  10232. void *data)
  10233. {
  10234. tree t = *tp;
  10235. /* Any variable with DECL_VALUE_EXPR needs to be regimplified. */
  10236. if (TREE_CODE (t) == VAR_DECL && data == NULL && DECL_HAS_VALUE_EXPR_P (t))
  10237. return t;
  10238. if (task_shared_vars
  10239. && DECL_P (t)
  10240. && bitmap_bit_p (task_shared_vars, DECL_UID (t)))
  10241. return t;
  10242. /* If a global variable has been privatized, TREE_CONSTANT on
  10243. ADDR_EXPR might be wrong. */
  10244. if (data == NULL && TREE_CODE (t) == ADDR_EXPR)
  10245. recompute_tree_invariant_for_addr_expr (t);
  10246. *walk_subtrees = !TYPE_P (t) && !DECL_P (t);
  10247. return NULL_TREE;
  10248. }
  10249. static void
  10250. lower_omp_1 (gimple_stmt_iterator *gsi_p, omp_context *ctx)
  10251. {
  10252. gimple stmt = gsi_stmt (*gsi_p);
  10253. struct walk_stmt_info wi;
  10254. gcall *call_stmt;
  10255. if (gimple_has_location (stmt))
  10256. input_location = gimple_location (stmt);
  10257. if (task_shared_vars)
  10258. memset (&wi, '\0', sizeof (wi));
  10259. /* If we have issued syntax errors, avoid doing any heavy lifting.
  10260. Just replace the OMP directives with a NOP to avoid
  10261. confusing RTL expansion. */
  10262. if (seen_error () && is_gimple_omp (stmt))
  10263. {
  10264. gsi_replace (gsi_p, gimple_build_nop (), true);
  10265. return;
  10266. }
  10267. switch (gimple_code (stmt))
  10268. {
  10269. case GIMPLE_COND:
  10270. {
  10271. gcond *cond_stmt = as_a <gcond *> (stmt);
  10272. if ((ctx || task_shared_vars)
  10273. && (walk_tree (gimple_cond_lhs_ptr (cond_stmt),
  10274. lower_omp_regimplify_p,
  10275. ctx ? NULL : &wi, NULL)
  10276. || walk_tree (gimple_cond_rhs_ptr (cond_stmt),
  10277. lower_omp_regimplify_p,
  10278. ctx ? NULL : &wi, NULL)))
  10279. gimple_regimplify_operands (cond_stmt, gsi_p);
  10280. }
  10281. break;
  10282. case GIMPLE_CATCH:
  10283. lower_omp (gimple_catch_handler_ptr (as_a <gcatch *> (stmt)), ctx);
  10284. break;
  10285. case GIMPLE_EH_FILTER:
  10286. lower_omp (gimple_eh_filter_failure_ptr (stmt), ctx);
  10287. break;
  10288. case GIMPLE_TRY:
  10289. lower_omp (gimple_try_eval_ptr (stmt), ctx);
  10290. lower_omp (gimple_try_cleanup_ptr (stmt), ctx);
  10291. break;
  10292. case GIMPLE_TRANSACTION:
  10293. lower_omp (gimple_transaction_body_ptr (
  10294. as_a <gtransaction *> (stmt)),
  10295. ctx);
  10296. break;
  10297. case GIMPLE_BIND:
  10298. lower_omp (gimple_bind_body_ptr (as_a <gbind *> (stmt)), ctx);
  10299. break;
  10300. case GIMPLE_OMP_PARALLEL:
  10301. case GIMPLE_OMP_TASK:
  10302. ctx = maybe_lookup_ctx (stmt);
  10303. gcc_assert (ctx);
  10304. if (ctx->cancellable)
  10305. ctx->cancel_label = create_artificial_label (UNKNOWN_LOCATION);
  10306. lower_omp_taskreg (gsi_p, ctx);
  10307. break;
  10308. case GIMPLE_OMP_FOR:
  10309. ctx = maybe_lookup_ctx (stmt);
  10310. gcc_assert (ctx);
  10311. if (ctx->cancellable)
  10312. ctx->cancel_label = create_artificial_label (UNKNOWN_LOCATION);
  10313. lower_omp_for (gsi_p, ctx);
  10314. break;
  10315. case GIMPLE_OMP_SECTIONS:
  10316. ctx = maybe_lookup_ctx (stmt);
  10317. gcc_assert (ctx);
  10318. if (ctx->cancellable)
  10319. ctx->cancel_label = create_artificial_label (UNKNOWN_LOCATION);
  10320. lower_omp_sections (gsi_p, ctx);
  10321. break;
  10322. case GIMPLE_OMP_SINGLE:
  10323. ctx = maybe_lookup_ctx (stmt);
  10324. gcc_assert (ctx);
  10325. lower_omp_single (gsi_p, ctx);
  10326. break;
  10327. case GIMPLE_OMP_MASTER:
  10328. ctx = maybe_lookup_ctx (stmt);
  10329. gcc_assert (ctx);
  10330. lower_omp_master (gsi_p, ctx);
  10331. break;
  10332. case GIMPLE_OMP_TASKGROUP:
  10333. ctx = maybe_lookup_ctx (stmt);
  10334. gcc_assert (ctx);
  10335. lower_omp_taskgroup (gsi_p, ctx);
  10336. break;
  10337. case GIMPLE_OMP_ORDERED:
  10338. ctx = maybe_lookup_ctx (stmt);
  10339. gcc_assert (ctx);
  10340. lower_omp_ordered (gsi_p, ctx);
  10341. break;
  10342. case GIMPLE_OMP_CRITICAL:
  10343. ctx = maybe_lookup_ctx (stmt);
  10344. gcc_assert (ctx);
  10345. lower_omp_critical (gsi_p, ctx);
  10346. break;
  10347. case GIMPLE_OMP_ATOMIC_LOAD:
  10348. if ((ctx || task_shared_vars)
  10349. && walk_tree (gimple_omp_atomic_load_rhs_ptr (
  10350. as_a <gomp_atomic_load *> (stmt)),
  10351. lower_omp_regimplify_p, ctx ? NULL : &wi, NULL))
  10352. gimple_regimplify_operands (stmt, gsi_p);
  10353. break;
  10354. case GIMPLE_OMP_TARGET:
  10355. ctx = maybe_lookup_ctx (stmt);
  10356. gcc_assert (ctx);
  10357. lower_omp_target (gsi_p, ctx);
  10358. break;
  10359. case GIMPLE_OMP_TEAMS:
  10360. ctx = maybe_lookup_ctx (stmt);
  10361. gcc_assert (ctx);
  10362. lower_omp_teams (gsi_p, ctx);
  10363. break;
  10364. case GIMPLE_CALL:
  10365. tree fndecl;
  10366. call_stmt = as_a <gcall *> (stmt);
  10367. fndecl = gimple_call_fndecl (call_stmt);
  10368. if (fndecl
  10369. && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
  10370. switch (DECL_FUNCTION_CODE (fndecl))
  10371. {
  10372. case BUILT_IN_GOMP_BARRIER:
  10373. if (ctx == NULL)
  10374. break;
  10375. /* FALLTHRU */
  10376. case BUILT_IN_GOMP_CANCEL:
  10377. case BUILT_IN_GOMP_CANCELLATION_POINT:
  10378. omp_context *cctx;
  10379. cctx = ctx;
  10380. if (gimple_code (cctx->stmt) == GIMPLE_OMP_SECTION)
  10381. cctx = cctx->outer;
  10382. gcc_assert (gimple_call_lhs (call_stmt) == NULL_TREE);
  10383. if (!cctx->cancellable)
  10384. {
  10385. if (DECL_FUNCTION_CODE (fndecl)
  10386. == BUILT_IN_GOMP_CANCELLATION_POINT)
  10387. {
  10388. stmt = gimple_build_nop ();
  10389. gsi_replace (gsi_p, stmt, false);
  10390. }
  10391. break;
  10392. }
  10393. if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_GOMP_BARRIER)
  10394. {
  10395. fndecl = builtin_decl_explicit (BUILT_IN_GOMP_BARRIER_CANCEL);
  10396. gimple_call_set_fndecl (call_stmt, fndecl);
  10397. gimple_call_set_fntype (call_stmt, TREE_TYPE (fndecl));
  10398. }
  10399. tree lhs;
  10400. lhs = create_tmp_var (TREE_TYPE (TREE_TYPE (fndecl)));
  10401. gimple_call_set_lhs (call_stmt, lhs);
  10402. tree fallthru_label;
  10403. fallthru_label = create_artificial_label (UNKNOWN_LOCATION);
  10404. gimple g;
  10405. g = gimple_build_label (fallthru_label);
  10406. gsi_insert_after (gsi_p, g, GSI_SAME_STMT);
  10407. g = gimple_build_cond (NE_EXPR, lhs,
  10408. fold_convert (TREE_TYPE (lhs),
  10409. boolean_false_node),
  10410. cctx->cancel_label, fallthru_label);
  10411. gsi_insert_after (gsi_p, g, GSI_SAME_STMT);
  10412. break;
  10413. default:
  10414. break;
  10415. }
  10416. /* FALLTHRU */
  10417. default:
  10418. if ((ctx || task_shared_vars)
  10419. && walk_gimple_op (stmt, lower_omp_regimplify_p,
  10420. ctx ? NULL : &wi))
  10421. {
  10422. /* Just remove clobbers, this should happen only if we have
  10423. "privatized" local addressable variables in SIMD regions,
  10424. the clobber isn't needed in that case and gimplifying address
  10425. of the ARRAY_REF into a pointer and creating MEM_REF based
  10426. clobber would create worse code than we get with the clobber
  10427. dropped. */
  10428. if (gimple_clobber_p (stmt))
  10429. {
  10430. gsi_replace (gsi_p, gimple_build_nop (), true);
  10431. break;
  10432. }
  10433. gimple_regimplify_operands (stmt, gsi_p);
  10434. }
  10435. break;
  10436. }
  10437. }
  10438. static void
  10439. lower_omp (gimple_seq *body, omp_context *ctx)
  10440. {
  10441. location_t saved_location = input_location;
  10442. gimple_stmt_iterator gsi;
  10443. for (gsi = gsi_start (*body); !gsi_end_p (gsi); gsi_next (&gsi))
  10444. lower_omp_1 (&gsi, ctx);
  10445. /* During gimplification, we haven't folded statments inside offloading
  10446. or taskreg regions (gimplify.c:maybe_fold_stmt); do that now. */
  10447. if (target_nesting_level || taskreg_nesting_level)
  10448. for (gsi = gsi_start (*body); !gsi_end_p (gsi); gsi_next (&gsi))
  10449. fold_stmt (&gsi);
  10450. input_location = saved_location;
  10451. }
  10452. /* Main entry point. */
  10453. static unsigned int
  10454. execute_lower_omp (void)
  10455. {
  10456. gimple_seq body;
  10457. int i;
  10458. omp_context *ctx;
  10459. /* This pass always runs, to provide PROP_gimple_lomp.
  10460. But often, there is nothing to do. */
  10461. if (flag_cilkplus == 0 && flag_openacc == 0 && flag_openmp == 0
  10462. && flag_openmp_simd == 0)
  10463. return 0;
  10464. all_contexts = splay_tree_new (splay_tree_compare_pointers, 0,
  10465. delete_omp_context);
  10466. body = gimple_body (current_function_decl);
  10467. scan_omp (&body, NULL);
  10468. gcc_assert (taskreg_nesting_level == 0);
  10469. FOR_EACH_VEC_ELT (taskreg_contexts, i, ctx)
  10470. finish_taskreg_scan (ctx);
  10471. taskreg_contexts.release ();
  10472. if (all_contexts->root)
  10473. {
  10474. if (task_shared_vars)
  10475. push_gimplify_context ();
  10476. lower_omp (&body, NULL);
  10477. if (task_shared_vars)
  10478. pop_gimplify_context (NULL);
  10479. }
  10480. if (all_contexts)
  10481. {
  10482. splay_tree_delete (all_contexts);
  10483. all_contexts = NULL;
  10484. }
  10485. BITMAP_FREE (task_shared_vars);
  10486. return 0;
  10487. }
  10488. namespace {
  10489. const pass_data pass_data_lower_omp =
  10490. {
  10491. GIMPLE_PASS, /* type */
  10492. "omplower", /* name */
  10493. OPTGROUP_NONE, /* optinfo_flags */
  10494. TV_NONE, /* tv_id */
  10495. PROP_gimple_any, /* properties_required */
  10496. PROP_gimple_lomp, /* properties_provided */
  10497. 0, /* properties_destroyed */
  10498. 0, /* todo_flags_start */
  10499. 0, /* todo_flags_finish */
  10500. };
  10501. class pass_lower_omp : public gimple_opt_pass
  10502. {
  10503. public:
  10504. pass_lower_omp (gcc::context *ctxt)
  10505. : gimple_opt_pass (pass_data_lower_omp, ctxt)
  10506. {}
  10507. /* opt_pass methods: */
  10508. virtual unsigned int execute (function *) { return execute_lower_omp (); }
  10509. }; // class pass_lower_omp
  10510. } // anon namespace
  10511. gimple_opt_pass *
  10512. make_pass_lower_omp (gcc::context *ctxt)
  10513. {
  10514. return new pass_lower_omp (ctxt);
  10515. }
  10516. /* The following is a utility to diagnose structured block violations.
  10517. It is not part of the "omplower" pass, as that's invoked too late. It
  10518. should be invoked by the respective front ends after gimplification. */
  10519. static splay_tree all_labels;
  10520. /* Check for mismatched contexts and generate an error if needed. Return
  10521. true if an error is detected. */
  10522. static bool
  10523. diagnose_sb_0 (gimple_stmt_iterator *gsi_p,
  10524. gimple branch_ctx, gimple label_ctx)
  10525. {
  10526. gcc_checking_assert (!branch_ctx || is_gimple_omp (branch_ctx));
  10527. gcc_checking_assert (!label_ctx || is_gimple_omp (label_ctx));
  10528. if (label_ctx == branch_ctx)
  10529. return false;
  10530. const char* kind = NULL;
  10531. if (flag_cilkplus)
  10532. {
  10533. if ((branch_ctx
  10534. && gimple_code (branch_ctx) == GIMPLE_OMP_FOR
  10535. && gimple_omp_for_kind (branch_ctx) == GF_OMP_FOR_KIND_CILKSIMD)
  10536. || (label_ctx
  10537. && gimple_code (label_ctx) == GIMPLE_OMP_FOR
  10538. && gimple_omp_for_kind (label_ctx) == GF_OMP_FOR_KIND_CILKSIMD))
  10539. kind = "Cilk Plus";
  10540. }
  10541. if (flag_openacc)
  10542. {
  10543. if ((branch_ctx && is_gimple_omp_oacc (branch_ctx))
  10544. || (label_ctx && is_gimple_omp_oacc (label_ctx)))
  10545. {
  10546. gcc_checking_assert (kind == NULL);
  10547. kind = "OpenACC";
  10548. }
  10549. }
  10550. if (kind == NULL)
  10551. {
  10552. gcc_checking_assert (flag_openmp);
  10553. kind = "OpenMP";
  10554. }
  10555. /*
  10556. Previously we kept track of the label's entire context in diagnose_sb_[12]
  10557. so we could traverse it and issue a correct "exit" or "enter" error
  10558. message upon a structured block violation.
  10559. We built the context by building a list with tree_cons'ing, but there is
  10560. no easy counterpart in gimple tuples. It seems like far too much work
  10561. for issuing exit/enter error messages. If someone really misses the
  10562. distinct error message... patches welcome.
  10563. */
  10564. #if 0
  10565. /* Try to avoid confusing the user by producing and error message
  10566. with correct "exit" or "enter" verbiage. We prefer "exit"
  10567. unless we can show that LABEL_CTX is nested within BRANCH_CTX. */
  10568. if (branch_ctx == NULL)
  10569. exit_p = false;
  10570. else
  10571. {
  10572. while (label_ctx)
  10573. {
  10574. if (TREE_VALUE (label_ctx) == branch_ctx)
  10575. {
  10576. exit_p = false;
  10577. break;
  10578. }
  10579. label_ctx = TREE_CHAIN (label_ctx);
  10580. }
  10581. }
  10582. if (exit_p)
  10583. error ("invalid exit from %s structured block", kind);
  10584. else
  10585. error ("invalid entry to %s structured block", kind);
  10586. #endif
  10587. /* If it's obvious we have an invalid entry, be specific about the error. */
  10588. if (branch_ctx == NULL)
  10589. error ("invalid entry to %s structured block", kind);
  10590. else
  10591. {
  10592. /* Otherwise, be vague and lazy, but efficient. */
  10593. error ("invalid branch to/from %s structured block", kind);
  10594. }
  10595. gsi_replace (gsi_p, gimple_build_nop (), false);
  10596. return true;
  10597. }
  10598. /* Pass 1: Create a minimal tree of structured blocks, and record
  10599. where each label is found. */
  10600. static tree
  10601. diagnose_sb_1 (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
  10602. struct walk_stmt_info *wi)
  10603. {
  10604. gimple context = (gimple) wi->info;
  10605. gimple inner_context;
  10606. gimple stmt = gsi_stmt (*gsi_p);
  10607. *handled_ops_p = true;
  10608. switch (gimple_code (stmt))
  10609. {
  10610. WALK_SUBSTMTS;
  10611. case GIMPLE_OMP_PARALLEL:
  10612. case GIMPLE_OMP_TASK:
  10613. case GIMPLE_OMP_SECTIONS:
  10614. case GIMPLE_OMP_SINGLE:
  10615. case GIMPLE_OMP_SECTION:
  10616. case GIMPLE_OMP_MASTER:
  10617. case GIMPLE_OMP_ORDERED:
  10618. case GIMPLE_OMP_CRITICAL:
  10619. case GIMPLE_OMP_TARGET:
  10620. case GIMPLE_OMP_TEAMS:
  10621. case GIMPLE_OMP_TASKGROUP:
  10622. /* The minimal context here is just the current OMP construct. */
  10623. inner_context = stmt;
  10624. wi->info = inner_context;
  10625. walk_gimple_seq (gimple_omp_body (stmt), diagnose_sb_1, NULL, wi);
  10626. wi->info = context;
  10627. break;
  10628. case GIMPLE_OMP_FOR:
  10629. inner_context = stmt;
  10630. wi->info = inner_context;
  10631. /* gimple_omp_for_{index,initial,final} are all DECLs; no need to
  10632. walk them. */
  10633. walk_gimple_seq (gimple_omp_for_pre_body (stmt),
  10634. diagnose_sb_1, NULL, wi);
  10635. walk_gimple_seq (gimple_omp_body (stmt), diagnose_sb_1, NULL, wi);
  10636. wi->info = context;
  10637. break;
  10638. case GIMPLE_LABEL:
  10639. splay_tree_insert (all_labels,
  10640. (splay_tree_key) gimple_label_label (
  10641. as_a <glabel *> (stmt)),
  10642. (splay_tree_value) context);
  10643. break;
  10644. default:
  10645. break;
  10646. }
  10647. return NULL_TREE;
  10648. }
  10649. /* Pass 2: Check each branch and see if its context differs from that of
  10650. the destination label's context. */
  10651. static tree
  10652. diagnose_sb_2 (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
  10653. struct walk_stmt_info *wi)
  10654. {
  10655. gimple context = (gimple) wi->info;
  10656. splay_tree_node n;
  10657. gimple stmt = gsi_stmt (*gsi_p);
  10658. *handled_ops_p = true;
  10659. switch (gimple_code (stmt))
  10660. {
  10661. WALK_SUBSTMTS;
  10662. case GIMPLE_OMP_PARALLEL:
  10663. case GIMPLE_OMP_TASK:
  10664. case GIMPLE_OMP_SECTIONS:
  10665. case GIMPLE_OMP_SINGLE:
  10666. case GIMPLE_OMP_SECTION:
  10667. case GIMPLE_OMP_MASTER:
  10668. case GIMPLE_OMP_ORDERED:
  10669. case GIMPLE_OMP_CRITICAL:
  10670. case GIMPLE_OMP_TARGET:
  10671. case GIMPLE_OMP_TEAMS:
  10672. case GIMPLE_OMP_TASKGROUP:
  10673. wi->info = stmt;
  10674. walk_gimple_seq_mod (gimple_omp_body_ptr (stmt), diagnose_sb_2, NULL, wi);
  10675. wi->info = context;
  10676. break;
  10677. case GIMPLE_OMP_FOR:
  10678. wi->info = stmt;
  10679. /* gimple_omp_for_{index,initial,final} are all DECLs; no need to
  10680. walk them. */
  10681. walk_gimple_seq_mod (gimple_omp_for_pre_body_ptr (stmt),
  10682. diagnose_sb_2, NULL, wi);
  10683. walk_gimple_seq_mod (gimple_omp_body_ptr (stmt), diagnose_sb_2, NULL, wi);
  10684. wi->info = context;
  10685. break;
  10686. case GIMPLE_COND:
  10687. {
  10688. gcond *cond_stmt = as_a <gcond *> (stmt);
  10689. tree lab = gimple_cond_true_label (cond_stmt);
  10690. if (lab)
  10691. {
  10692. n = splay_tree_lookup (all_labels,
  10693. (splay_tree_key) lab);
  10694. diagnose_sb_0 (gsi_p, context,
  10695. n ? (gimple) n->value : NULL);
  10696. }
  10697. lab = gimple_cond_false_label (cond_stmt);
  10698. if (lab)
  10699. {
  10700. n = splay_tree_lookup (all_labels,
  10701. (splay_tree_key) lab);
  10702. diagnose_sb_0 (gsi_p, context,
  10703. n ? (gimple) n->value : NULL);
  10704. }
  10705. }
  10706. break;
  10707. case GIMPLE_GOTO:
  10708. {
  10709. tree lab = gimple_goto_dest (stmt);
  10710. if (TREE_CODE (lab) != LABEL_DECL)
  10711. break;
  10712. n = splay_tree_lookup (all_labels, (splay_tree_key) lab);
  10713. diagnose_sb_0 (gsi_p, context, n ? (gimple) n->value : NULL);
  10714. }
  10715. break;
  10716. case GIMPLE_SWITCH:
  10717. {
  10718. gswitch *switch_stmt = as_a <gswitch *> (stmt);
  10719. unsigned int i;
  10720. for (i = 0; i < gimple_switch_num_labels (switch_stmt); ++i)
  10721. {
  10722. tree lab = CASE_LABEL (gimple_switch_label (switch_stmt, i));
  10723. n = splay_tree_lookup (all_labels, (splay_tree_key) lab);
  10724. if (n && diagnose_sb_0 (gsi_p, context, (gimple) n->value))
  10725. break;
  10726. }
  10727. }
  10728. break;
  10729. case GIMPLE_RETURN:
  10730. diagnose_sb_0 (gsi_p, context, NULL);
  10731. break;
  10732. default:
  10733. break;
  10734. }
  10735. return NULL_TREE;
  10736. }
  10737. /* Called from tree-cfg.c::make_edges to create cfg edges for all relevant
  10738. GIMPLE_* codes. */
  10739. bool
  10740. make_gimple_omp_edges (basic_block bb, struct omp_region **region,
  10741. int *region_idx)
  10742. {
  10743. gimple last = last_stmt (bb);
  10744. enum gimple_code code = gimple_code (last);
  10745. struct omp_region *cur_region = *region;
  10746. bool fallthru = false;
  10747. switch (code)
  10748. {
  10749. case GIMPLE_OMP_PARALLEL:
  10750. case GIMPLE_OMP_TASK:
  10751. case GIMPLE_OMP_FOR:
  10752. case GIMPLE_OMP_SINGLE:
  10753. case GIMPLE_OMP_TEAMS:
  10754. case GIMPLE_OMP_MASTER:
  10755. case GIMPLE_OMP_TASKGROUP:
  10756. case GIMPLE_OMP_ORDERED:
  10757. case GIMPLE_OMP_CRITICAL:
  10758. case GIMPLE_OMP_SECTION:
  10759. cur_region = new_omp_region (bb, code, cur_region);
  10760. fallthru = true;
  10761. break;
  10762. case GIMPLE_OMP_TARGET:
  10763. cur_region = new_omp_region (bb, code, cur_region);
  10764. fallthru = true;
  10765. switch (gimple_omp_target_kind (last))
  10766. {
  10767. case GF_OMP_TARGET_KIND_REGION:
  10768. case GF_OMP_TARGET_KIND_DATA:
  10769. case GF_OMP_TARGET_KIND_OACC_PARALLEL:
  10770. case GF_OMP_TARGET_KIND_OACC_KERNELS:
  10771. case GF_OMP_TARGET_KIND_OACC_DATA:
  10772. break;
  10773. case GF_OMP_TARGET_KIND_UPDATE:
  10774. case GF_OMP_TARGET_KIND_OACC_UPDATE:
  10775. case GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA:
  10776. cur_region = cur_region->outer;
  10777. break;
  10778. default:
  10779. gcc_unreachable ();
  10780. }
  10781. break;
  10782. case GIMPLE_OMP_SECTIONS:
  10783. cur_region = new_omp_region (bb, code, cur_region);
  10784. fallthru = true;
  10785. break;
  10786. case GIMPLE_OMP_SECTIONS_SWITCH:
  10787. fallthru = false;
  10788. break;
  10789. case GIMPLE_OMP_ATOMIC_LOAD:
  10790. case GIMPLE_OMP_ATOMIC_STORE:
  10791. fallthru = true;
  10792. break;
  10793. case GIMPLE_OMP_RETURN:
  10794. /* In the case of a GIMPLE_OMP_SECTION, the edge will go
  10795. somewhere other than the next block. This will be
  10796. created later. */
  10797. cur_region->exit = bb;
  10798. if (cur_region->type == GIMPLE_OMP_TASK)
  10799. /* Add an edge corresponding to not scheduling the task
  10800. immediately. */
  10801. make_edge (cur_region->entry, bb, EDGE_ABNORMAL);
  10802. fallthru = cur_region->type != GIMPLE_OMP_SECTION;
  10803. cur_region = cur_region->outer;
  10804. break;
  10805. case GIMPLE_OMP_CONTINUE:
  10806. cur_region->cont = bb;
  10807. switch (cur_region->type)
  10808. {
  10809. case GIMPLE_OMP_FOR:
  10810. /* Mark all GIMPLE_OMP_FOR and GIMPLE_OMP_CONTINUE
  10811. succs edges as abnormal to prevent splitting
  10812. them. */
  10813. single_succ_edge (cur_region->entry)->flags |= EDGE_ABNORMAL;
  10814. /* Make the loopback edge. */
  10815. make_edge (bb, single_succ (cur_region->entry),
  10816. EDGE_ABNORMAL);
  10817. /* Create an edge from GIMPLE_OMP_FOR to exit, which
  10818. corresponds to the case that the body of the loop
  10819. is not executed at all. */
  10820. make_edge (cur_region->entry, bb->next_bb, EDGE_ABNORMAL);
  10821. make_edge (bb, bb->next_bb, EDGE_FALLTHRU | EDGE_ABNORMAL);
  10822. fallthru = false;
  10823. break;
  10824. case GIMPLE_OMP_SECTIONS:
  10825. /* Wire up the edges into and out of the nested sections. */
  10826. {
  10827. basic_block switch_bb = single_succ (cur_region->entry);
  10828. struct omp_region *i;
  10829. for (i = cur_region->inner; i ; i = i->next)
  10830. {
  10831. gcc_assert (i->type == GIMPLE_OMP_SECTION);
  10832. make_edge (switch_bb, i->entry, 0);
  10833. make_edge (i->exit, bb, EDGE_FALLTHRU);
  10834. }
  10835. /* Make the loopback edge to the block with
  10836. GIMPLE_OMP_SECTIONS_SWITCH. */
  10837. make_edge (bb, switch_bb, 0);
  10838. /* Make the edge from the switch to exit. */
  10839. make_edge (switch_bb, bb->next_bb, 0);
  10840. fallthru = false;
  10841. }
  10842. break;
  10843. case GIMPLE_OMP_TASK:
  10844. fallthru = true;
  10845. break;
  10846. default:
  10847. gcc_unreachable ();
  10848. }
  10849. break;
  10850. default:
  10851. gcc_unreachable ();
  10852. }
  10853. if (*region != cur_region)
  10854. {
  10855. *region = cur_region;
  10856. if (cur_region)
  10857. *region_idx = cur_region->entry->index;
  10858. else
  10859. *region_idx = 0;
  10860. }
  10861. return fallthru;
  10862. }
  10863. static unsigned int
  10864. diagnose_omp_structured_block_errors (void)
  10865. {
  10866. struct walk_stmt_info wi;
  10867. gimple_seq body = gimple_body (current_function_decl);
  10868. all_labels = splay_tree_new (splay_tree_compare_pointers, 0, 0);
  10869. memset (&wi, 0, sizeof (wi));
  10870. walk_gimple_seq (body, diagnose_sb_1, NULL, &wi);
  10871. memset (&wi, 0, sizeof (wi));
  10872. wi.want_locations = true;
  10873. walk_gimple_seq_mod (&body, diagnose_sb_2, NULL, &wi);
  10874. gimple_set_body (current_function_decl, body);
  10875. splay_tree_delete (all_labels);
  10876. all_labels = NULL;
  10877. return 0;
  10878. }
  10879. namespace {
  10880. const pass_data pass_data_diagnose_omp_blocks =
  10881. {
  10882. GIMPLE_PASS, /* type */
  10883. "*diagnose_omp_blocks", /* name */
  10884. OPTGROUP_NONE, /* optinfo_flags */
  10885. TV_NONE, /* tv_id */
  10886. PROP_gimple_any, /* properties_required */
  10887. 0, /* properties_provided */
  10888. 0, /* properties_destroyed */
  10889. 0, /* todo_flags_start */
  10890. 0, /* todo_flags_finish */
  10891. };
  10892. class pass_diagnose_omp_blocks : public gimple_opt_pass
  10893. {
  10894. public:
  10895. pass_diagnose_omp_blocks (gcc::context *ctxt)
  10896. : gimple_opt_pass (pass_data_diagnose_omp_blocks, ctxt)
  10897. {}
  10898. /* opt_pass methods: */
  10899. virtual bool gate (function *)
  10900. {
  10901. return flag_cilkplus || flag_openacc || flag_openmp;
  10902. }
  10903. virtual unsigned int execute (function *)
  10904. {
  10905. return diagnose_omp_structured_block_errors ();
  10906. }
  10907. }; // class pass_diagnose_omp_blocks
  10908. } // anon namespace
  10909. gimple_opt_pass *
  10910. make_pass_diagnose_omp_blocks (gcc::context *ctxt)
  10911. {
  10912. return new pass_diagnose_omp_blocks (ctxt);
  10913. }
  10914. /* SIMD clone supporting code. */
  10915. /* Allocate a fresh `simd_clone' and return it. NARGS is the number
  10916. of arguments to reserve space for. */
  10917. static struct cgraph_simd_clone *
  10918. simd_clone_struct_alloc (int nargs)
  10919. {
  10920. struct cgraph_simd_clone *clone_info;
  10921. size_t len = (sizeof (struct cgraph_simd_clone)
  10922. + nargs * sizeof (struct cgraph_simd_clone_arg));
  10923. clone_info = (struct cgraph_simd_clone *)
  10924. ggc_internal_cleared_alloc (len);
  10925. return clone_info;
  10926. }
  10927. /* Make a copy of the `struct cgraph_simd_clone' in FROM to TO. */
  10928. static inline void
  10929. simd_clone_struct_copy (struct cgraph_simd_clone *to,
  10930. struct cgraph_simd_clone *from)
  10931. {
  10932. memcpy (to, from, (sizeof (struct cgraph_simd_clone)
  10933. + ((from->nargs - from->inbranch)
  10934. * sizeof (struct cgraph_simd_clone_arg))));
  10935. }
  10936. /* Return vector of parameter types of function FNDECL. This uses
  10937. TYPE_ARG_TYPES if available, otherwise falls back to types of
  10938. DECL_ARGUMENTS types. */
  10939. vec<tree>
  10940. simd_clone_vector_of_formal_parm_types (tree fndecl)
  10941. {
  10942. if (TYPE_ARG_TYPES (TREE_TYPE (fndecl)))
  10943. return ipa_get_vector_of_formal_parm_types (TREE_TYPE (fndecl));
  10944. vec<tree> args = ipa_get_vector_of_formal_parms (fndecl);
  10945. unsigned int i;
  10946. tree arg;
  10947. FOR_EACH_VEC_ELT (args, i, arg)
  10948. args[i] = TREE_TYPE (args[i]);
  10949. return args;
  10950. }
  10951. /* Given a simd function in NODE, extract the simd specific
  10952. information from the OMP clauses passed in CLAUSES, and return
  10953. the struct cgraph_simd_clone * if it should be cloned. *INBRANCH_SPECIFIED
  10954. is set to TRUE if the `inbranch' or `notinbranch' clause specified,
  10955. otherwise set to FALSE. */
  10956. static struct cgraph_simd_clone *
  10957. simd_clone_clauses_extract (struct cgraph_node *node, tree clauses,
  10958. bool *inbranch_specified)
  10959. {
  10960. vec<tree> args = simd_clone_vector_of_formal_parm_types (node->decl);
  10961. tree t;
  10962. int n;
  10963. *inbranch_specified = false;
  10964. n = args.length ();
  10965. if (n > 0 && args.last () == void_type_node)
  10966. n--;
  10967. /* To distinguish from an OpenMP simd clone, Cilk Plus functions to
  10968. be cloned have a distinctive artificial label in addition to "omp
  10969. declare simd". */
  10970. bool cilk_clone
  10971. = (flag_cilkplus
  10972. && lookup_attribute ("cilk simd function",
  10973. DECL_ATTRIBUTES (node->decl)));
  10974. /* Allocate one more than needed just in case this is an in-branch
  10975. clone which will require a mask argument. */
  10976. struct cgraph_simd_clone *clone_info = simd_clone_struct_alloc (n + 1);
  10977. clone_info->nargs = n;
  10978. clone_info->cilk_elemental = cilk_clone;
  10979. if (!clauses)
  10980. {
  10981. args.release ();
  10982. return clone_info;
  10983. }
  10984. clauses = TREE_VALUE (clauses);
  10985. if (!clauses || TREE_CODE (clauses) != OMP_CLAUSE)
  10986. return clone_info;
  10987. for (t = clauses; t; t = OMP_CLAUSE_CHAIN (t))
  10988. {
  10989. switch (OMP_CLAUSE_CODE (t))
  10990. {
  10991. case OMP_CLAUSE_INBRANCH:
  10992. clone_info->inbranch = 1;
  10993. *inbranch_specified = true;
  10994. break;
  10995. case OMP_CLAUSE_NOTINBRANCH:
  10996. clone_info->inbranch = 0;
  10997. *inbranch_specified = true;
  10998. break;
  10999. case OMP_CLAUSE_SIMDLEN:
  11000. clone_info->simdlen
  11001. = TREE_INT_CST_LOW (OMP_CLAUSE_SIMDLEN_EXPR (t));
  11002. break;
  11003. case OMP_CLAUSE_LINEAR:
  11004. {
  11005. tree decl = OMP_CLAUSE_DECL (t);
  11006. tree step = OMP_CLAUSE_LINEAR_STEP (t);
  11007. int argno = TREE_INT_CST_LOW (decl);
  11008. if (OMP_CLAUSE_LINEAR_VARIABLE_STRIDE (t))
  11009. {
  11010. clone_info->args[argno].arg_type
  11011. = SIMD_CLONE_ARG_TYPE_LINEAR_VARIABLE_STEP;
  11012. clone_info->args[argno].linear_step = tree_to_shwi (step);
  11013. gcc_assert (clone_info->args[argno].linear_step >= 0
  11014. && clone_info->args[argno].linear_step < n);
  11015. }
  11016. else
  11017. {
  11018. if (POINTER_TYPE_P (args[argno]))
  11019. step = fold_convert (ssizetype, step);
  11020. if (!tree_fits_shwi_p (step))
  11021. {
  11022. warning_at (OMP_CLAUSE_LOCATION (t), 0,
  11023. "ignoring large linear step");
  11024. args.release ();
  11025. return NULL;
  11026. }
  11027. else if (integer_zerop (step))
  11028. {
  11029. warning_at (OMP_CLAUSE_LOCATION (t), 0,
  11030. "ignoring zero linear step");
  11031. args.release ();
  11032. return NULL;
  11033. }
  11034. else
  11035. {
  11036. clone_info->args[argno].arg_type
  11037. = SIMD_CLONE_ARG_TYPE_LINEAR_CONSTANT_STEP;
  11038. clone_info->args[argno].linear_step = tree_to_shwi (step);
  11039. }
  11040. }
  11041. break;
  11042. }
  11043. case OMP_CLAUSE_UNIFORM:
  11044. {
  11045. tree decl = OMP_CLAUSE_DECL (t);
  11046. int argno = tree_to_uhwi (decl);
  11047. clone_info->args[argno].arg_type
  11048. = SIMD_CLONE_ARG_TYPE_UNIFORM;
  11049. break;
  11050. }
  11051. case OMP_CLAUSE_ALIGNED:
  11052. {
  11053. tree decl = OMP_CLAUSE_DECL (t);
  11054. int argno = tree_to_uhwi (decl);
  11055. clone_info->args[argno].alignment
  11056. = TREE_INT_CST_LOW (OMP_CLAUSE_ALIGNED_ALIGNMENT (t));
  11057. break;
  11058. }
  11059. default:
  11060. break;
  11061. }
  11062. }
  11063. args.release ();
  11064. return clone_info;
  11065. }
  11066. /* Given a SIMD clone in NODE, calculate the characteristic data
  11067. type and return the coresponding type. The characteristic data
  11068. type is computed as described in the Intel Vector ABI. */
  11069. static tree
  11070. simd_clone_compute_base_data_type (struct cgraph_node *node,
  11071. struct cgraph_simd_clone *clone_info)
  11072. {
  11073. tree type = integer_type_node;
  11074. tree fndecl = node->decl;
  11075. /* a) For non-void function, the characteristic data type is the
  11076. return type. */
  11077. if (TREE_CODE (TREE_TYPE (TREE_TYPE (fndecl))) != VOID_TYPE)
  11078. type = TREE_TYPE (TREE_TYPE (fndecl));
  11079. /* b) If the function has any non-uniform, non-linear parameters,
  11080. then the characteristic data type is the type of the first
  11081. such parameter. */
  11082. else
  11083. {
  11084. vec<tree> map = simd_clone_vector_of_formal_parm_types (fndecl);
  11085. for (unsigned int i = 0; i < clone_info->nargs; ++i)
  11086. if (clone_info->args[i].arg_type == SIMD_CLONE_ARG_TYPE_VECTOR)
  11087. {
  11088. type = map[i];
  11089. break;
  11090. }
  11091. map.release ();
  11092. }
  11093. /* c) If the characteristic data type determined by a) or b) above
  11094. is struct, union, or class type which is pass-by-value (except
  11095. for the type that maps to the built-in complex data type), the
  11096. characteristic data type is int. */
  11097. if (RECORD_OR_UNION_TYPE_P (type)
  11098. && !aggregate_value_p (type, NULL)
  11099. && TREE_CODE (type) != COMPLEX_TYPE)
  11100. return integer_type_node;
  11101. /* d) If none of the above three classes is applicable, the
  11102. characteristic data type is int. */
  11103. return type;
  11104. /* e) For Intel Xeon Phi native and offload compilation, if the
  11105. resulting characteristic data type is 8-bit or 16-bit integer
  11106. data type, the characteristic data type is int. */
  11107. /* Well, we don't handle Xeon Phi yet. */
  11108. }
  11109. static tree
  11110. simd_clone_mangle (struct cgraph_node *node,
  11111. struct cgraph_simd_clone *clone_info)
  11112. {
  11113. char vecsize_mangle = clone_info->vecsize_mangle;
  11114. char mask = clone_info->inbranch ? 'M' : 'N';
  11115. unsigned int simdlen = clone_info->simdlen;
  11116. unsigned int n;
  11117. pretty_printer pp;
  11118. gcc_assert (vecsize_mangle && simdlen);
  11119. pp_string (&pp, "_ZGV");
  11120. pp_character (&pp, vecsize_mangle);
  11121. pp_character (&pp, mask);
  11122. pp_decimal_int (&pp, simdlen);
  11123. for (n = 0; n < clone_info->nargs; ++n)
  11124. {
  11125. struct cgraph_simd_clone_arg arg = clone_info->args[n];
  11126. if (arg.arg_type == SIMD_CLONE_ARG_TYPE_UNIFORM)
  11127. pp_character (&pp, 'u');
  11128. else if (arg.arg_type == SIMD_CLONE_ARG_TYPE_LINEAR_CONSTANT_STEP)
  11129. {
  11130. gcc_assert (arg.linear_step != 0);
  11131. pp_character (&pp, 'l');
  11132. if (arg.linear_step > 1)
  11133. pp_unsigned_wide_integer (&pp, arg.linear_step);
  11134. else if (arg.linear_step < 0)
  11135. {
  11136. pp_character (&pp, 'n');
  11137. pp_unsigned_wide_integer (&pp, (-(unsigned HOST_WIDE_INT)
  11138. arg.linear_step));
  11139. }
  11140. }
  11141. else if (arg.arg_type == SIMD_CLONE_ARG_TYPE_LINEAR_VARIABLE_STEP)
  11142. {
  11143. pp_character (&pp, 's');
  11144. pp_unsigned_wide_integer (&pp, arg.linear_step);
  11145. }
  11146. else
  11147. pp_character (&pp, 'v');
  11148. if (arg.alignment)
  11149. {
  11150. pp_character (&pp, 'a');
  11151. pp_decimal_int (&pp, arg.alignment);
  11152. }
  11153. }
  11154. pp_underscore (&pp);
  11155. const char *str = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (node->decl));
  11156. if (*str == '*')
  11157. ++str;
  11158. pp_string (&pp, str);
  11159. str = pp_formatted_text (&pp);
  11160. /* If there already is a SIMD clone with the same mangled name, don't
  11161. add another one. This can happen e.g. for
  11162. #pragma omp declare simd
  11163. #pragma omp declare simd simdlen(8)
  11164. int foo (int, int);
  11165. if the simdlen is assumed to be 8 for the first one, etc. */
  11166. for (struct cgraph_node *clone = node->simd_clones; clone;
  11167. clone = clone->simdclone->next_clone)
  11168. if (strcmp (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (clone->decl)),
  11169. str) == 0)
  11170. return NULL_TREE;
  11171. return get_identifier (str);
  11172. }
  11173. /* Create a simd clone of OLD_NODE and return it. */
  11174. static struct cgraph_node *
  11175. simd_clone_create (struct cgraph_node *old_node)
  11176. {
  11177. struct cgraph_node *new_node;
  11178. if (old_node->definition)
  11179. {
  11180. if (!old_node->has_gimple_body_p ())
  11181. return NULL;
  11182. old_node->get_body ();
  11183. new_node = old_node->create_version_clone_with_body (vNULL, NULL, NULL,
  11184. false, NULL, NULL,
  11185. "simdclone");
  11186. }
  11187. else
  11188. {
  11189. tree old_decl = old_node->decl;
  11190. tree new_decl = copy_node (old_node->decl);
  11191. DECL_NAME (new_decl) = clone_function_name (old_decl, "simdclone");
  11192. SET_DECL_ASSEMBLER_NAME (new_decl, DECL_NAME (new_decl));
  11193. SET_DECL_RTL (new_decl, NULL);
  11194. DECL_STATIC_CONSTRUCTOR (new_decl) = 0;
  11195. DECL_STATIC_DESTRUCTOR (new_decl) = 0;
  11196. new_node = old_node->create_version_clone (new_decl, vNULL, NULL);
  11197. symtab->call_cgraph_insertion_hooks (new_node);
  11198. }
  11199. if (new_node == NULL)
  11200. return new_node;
  11201. TREE_PUBLIC (new_node->decl) = TREE_PUBLIC (old_node->decl);
  11202. /* The function cgraph_function_versioning () will force the new
  11203. symbol local. Undo this, and inherit external visability from
  11204. the old node. */
  11205. new_node->local.local = old_node->local.local;
  11206. new_node->externally_visible = old_node->externally_visible;
  11207. return new_node;
  11208. }
  11209. /* Adjust the return type of the given function to its appropriate
  11210. vector counterpart. Returns a simd array to be used throughout the
  11211. function as a return value. */
  11212. static tree
  11213. simd_clone_adjust_return_type (struct cgraph_node *node)
  11214. {
  11215. tree fndecl = node->decl;
  11216. tree orig_rettype = TREE_TYPE (TREE_TYPE (fndecl));
  11217. unsigned int veclen;
  11218. tree t;
  11219. /* Adjust the function return type. */
  11220. if (orig_rettype == void_type_node)
  11221. return NULL_TREE;
  11222. TREE_TYPE (fndecl) = build_distinct_type_copy (TREE_TYPE (fndecl));
  11223. t = TREE_TYPE (TREE_TYPE (fndecl));
  11224. if (INTEGRAL_TYPE_P (t) || POINTER_TYPE_P (t))
  11225. veclen = node->simdclone->vecsize_int;
  11226. else
  11227. veclen = node->simdclone->vecsize_float;
  11228. veclen /= GET_MODE_BITSIZE (TYPE_MODE (t));
  11229. if (veclen > node->simdclone->simdlen)
  11230. veclen = node->simdclone->simdlen;
  11231. if (POINTER_TYPE_P (t))
  11232. t = pointer_sized_int_node;
  11233. if (veclen == node->simdclone->simdlen)
  11234. t = build_vector_type (t, node->simdclone->simdlen);
  11235. else
  11236. {
  11237. t = build_vector_type (t, veclen);
  11238. t = build_array_type_nelts (t, node->simdclone->simdlen / veclen);
  11239. }
  11240. TREE_TYPE (TREE_TYPE (fndecl)) = t;
  11241. if (!node->definition)
  11242. return NULL_TREE;
  11243. t = DECL_RESULT (fndecl);
  11244. /* Adjust the DECL_RESULT. */
  11245. gcc_assert (TREE_TYPE (t) != void_type_node);
  11246. TREE_TYPE (t) = TREE_TYPE (TREE_TYPE (fndecl));
  11247. relayout_decl (t);
  11248. tree atype = build_array_type_nelts (orig_rettype,
  11249. node->simdclone->simdlen);
  11250. if (veclen != node->simdclone->simdlen)
  11251. return build1 (VIEW_CONVERT_EXPR, atype, t);
  11252. /* Set up a SIMD array to use as the return value. */
  11253. tree retval = create_tmp_var_raw (atype, "retval");
  11254. gimple_add_tmp_var (retval);
  11255. return retval;
  11256. }
  11257. /* Each vector argument has a corresponding array to be used locally
  11258. as part of the eventual loop. Create such temporary array and
  11259. return it.
  11260. PREFIX is the prefix to be used for the temporary.
  11261. TYPE is the inner element type.
  11262. SIMDLEN is the number of elements. */
  11263. static tree
  11264. create_tmp_simd_array (const char *prefix, tree type, int simdlen)
  11265. {
  11266. tree atype = build_array_type_nelts (type, simdlen);
  11267. tree avar = create_tmp_var_raw (atype, prefix);
  11268. gimple_add_tmp_var (avar);
  11269. return avar;
  11270. }
  11271. /* Modify the function argument types to their corresponding vector
  11272. counterparts if appropriate. Also, create one array for each simd
  11273. argument to be used locally when using the function arguments as
  11274. part of the loop.
  11275. NODE is the function whose arguments are to be adjusted.
  11276. Returns an adjustment vector that will be filled describing how the
  11277. argument types will be adjusted. */
  11278. static ipa_parm_adjustment_vec
  11279. simd_clone_adjust_argument_types (struct cgraph_node *node)
  11280. {
  11281. vec<tree> args;
  11282. ipa_parm_adjustment_vec adjustments;
  11283. if (node->definition)
  11284. args = ipa_get_vector_of_formal_parms (node->decl);
  11285. else
  11286. args = simd_clone_vector_of_formal_parm_types (node->decl);
  11287. adjustments.create (args.length ());
  11288. unsigned i, j, veclen;
  11289. struct ipa_parm_adjustment adj;
  11290. for (i = 0; i < node->simdclone->nargs; ++i)
  11291. {
  11292. memset (&adj, 0, sizeof (adj));
  11293. tree parm = args[i];
  11294. tree parm_type = node->definition ? TREE_TYPE (parm) : parm;
  11295. adj.base_index = i;
  11296. adj.base = parm;
  11297. node->simdclone->args[i].orig_arg = node->definition ? parm : NULL_TREE;
  11298. node->simdclone->args[i].orig_type = parm_type;
  11299. if (node->simdclone->args[i].arg_type != SIMD_CLONE_ARG_TYPE_VECTOR)
  11300. {
  11301. /* No adjustment necessary for scalar arguments. */
  11302. adj.op = IPA_PARM_OP_COPY;
  11303. }
  11304. else
  11305. {
  11306. if (INTEGRAL_TYPE_P (parm_type) || POINTER_TYPE_P (parm_type))
  11307. veclen = node->simdclone->vecsize_int;
  11308. else
  11309. veclen = node->simdclone->vecsize_float;
  11310. veclen /= GET_MODE_BITSIZE (TYPE_MODE (parm_type));
  11311. if (veclen > node->simdclone->simdlen)
  11312. veclen = node->simdclone->simdlen;
  11313. adj.arg_prefix = "simd";
  11314. if (POINTER_TYPE_P (parm_type))
  11315. adj.type = build_vector_type (pointer_sized_int_node, veclen);
  11316. else
  11317. adj.type = build_vector_type (parm_type, veclen);
  11318. node->simdclone->args[i].vector_type = adj.type;
  11319. for (j = veclen; j < node->simdclone->simdlen; j += veclen)
  11320. {
  11321. adjustments.safe_push (adj);
  11322. if (j == veclen)
  11323. {
  11324. memset (&adj, 0, sizeof (adj));
  11325. adj.op = IPA_PARM_OP_NEW;
  11326. adj.arg_prefix = "simd";
  11327. adj.base_index = i;
  11328. adj.type = node->simdclone->args[i].vector_type;
  11329. }
  11330. }
  11331. if (node->definition)
  11332. node->simdclone->args[i].simd_array
  11333. = create_tmp_simd_array (IDENTIFIER_POINTER (DECL_NAME (parm)),
  11334. parm_type, node->simdclone->simdlen);
  11335. }
  11336. adjustments.safe_push (adj);
  11337. }
  11338. if (node->simdclone->inbranch)
  11339. {
  11340. tree base_type
  11341. = simd_clone_compute_base_data_type (node->simdclone->origin,
  11342. node->simdclone);
  11343. memset (&adj, 0, sizeof (adj));
  11344. adj.op = IPA_PARM_OP_NEW;
  11345. adj.arg_prefix = "mask";
  11346. adj.base_index = i;
  11347. if (INTEGRAL_TYPE_P (base_type) || POINTER_TYPE_P (base_type))
  11348. veclen = node->simdclone->vecsize_int;
  11349. else
  11350. veclen = node->simdclone->vecsize_float;
  11351. veclen /= GET_MODE_BITSIZE (TYPE_MODE (base_type));
  11352. if (veclen > node->simdclone->simdlen)
  11353. veclen = node->simdclone->simdlen;
  11354. if (POINTER_TYPE_P (base_type))
  11355. adj.type = build_vector_type (pointer_sized_int_node, veclen);
  11356. else
  11357. adj.type = build_vector_type (base_type, veclen);
  11358. adjustments.safe_push (adj);
  11359. for (j = veclen; j < node->simdclone->simdlen; j += veclen)
  11360. adjustments.safe_push (adj);
  11361. /* We have previously allocated one extra entry for the mask. Use
  11362. it and fill it. */
  11363. struct cgraph_simd_clone *sc = node->simdclone;
  11364. sc->nargs++;
  11365. if (node->definition)
  11366. {
  11367. sc->args[i].orig_arg
  11368. = build_decl (UNKNOWN_LOCATION, PARM_DECL, NULL, base_type);
  11369. sc->args[i].simd_array
  11370. = create_tmp_simd_array ("mask", base_type, sc->simdlen);
  11371. }
  11372. sc->args[i].orig_type = base_type;
  11373. sc->args[i].arg_type = SIMD_CLONE_ARG_TYPE_MASK;
  11374. }
  11375. if (node->definition)
  11376. ipa_modify_formal_parameters (node->decl, adjustments);
  11377. else
  11378. {
  11379. tree new_arg_types = NULL_TREE, new_reversed;
  11380. bool last_parm_void = false;
  11381. if (args.length () > 0 && args.last () == void_type_node)
  11382. last_parm_void = true;
  11383. gcc_assert (TYPE_ARG_TYPES (TREE_TYPE (node->decl)));
  11384. j = adjustments.length ();
  11385. for (i = 0; i < j; i++)
  11386. {
  11387. struct ipa_parm_adjustment *adj = &adjustments[i];
  11388. tree ptype;
  11389. if (adj->op == IPA_PARM_OP_COPY)
  11390. ptype = args[adj->base_index];
  11391. else
  11392. ptype = adj->type;
  11393. new_arg_types = tree_cons (NULL_TREE, ptype, new_arg_types);
  11394. }
  11395. new_reversed = nreverse (new_arg_types);
  11396. if (last_parm_void)
  11397. {
  11398. if (new_reversed)
  11399. TREE_CHAIN (new_arg_types) = void_list_node;
  11400. else
  11401. new_reversed = void_list_node;
  11402. }
  11403. tree new_type = build_distinct_type_copy (TREE_TYPE (node->decl));
  11404. TYPE_ARG_TYPES (new_type) = new_reversed;
  11405. TREE_TYPE (node->decl) = new_type;
  11406. adjustments.release ();
  11407. }
  11408. args.release ();
  11409. return adjustments;
  11410. }
  11411. /* Initialize and copy the function arguments in NODE to their
  11412. corresponding local simd arrays. Returns a fresh gimple_seq with
  11413. the instruction sequence generated. */
  11414. static gimple_seq
  11415. simd_clone_init_simd_arrays (struct cgraph_node *node,
  11416. ipa_parm_adjustment_vec adjustments)
  11417. {
  11418. gimple_seq seq = NULL;
  11419. unsigned i = 0, j = 0, k;
  11420. for (tree arg = DECL_ARGUMENTS (node->decl);
  11421. arg;
  11422. arg = DECL_CHAIN (arg), i++, j++)
  11423. {
  11424. if (adjustments[j].op == IPA_PARM_OP_COPY)
  11425. continue;
  11426. node->simdclone->args[i].vector_arg = arg;
  11427. tree array = node->simdclone->args[i].simd_array;
  11428. if (TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg)) == node->simdclone->simdlen)
  11429. {
  11430. tree ptype = build_pointer_type (TREE_TYPE (TREE_TYPE (array)));
  11431. tree ptr = build_fold_addr_expr (array);
  11432. tree t = build2 (MEM_REF, TREE_TYPE (arg), ptr,
  11433. build_int_cst (ptype, 0));
  11434. t = build2 (MODIFY_EXPR, TREE_TYPE (t), t, arg);
  11435. gimplify_and_add (t, &seq);
  11436. }
  11437. else
  11438. {
  11439. unsigned int simdlen = TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg));
  11440. tree ptype = build_pointer_type (TREE_TYPE (TREE_TYPE (array)));
  11441. for (k = 0; k < node->simdclone->simdlen; k += simdlen)
  11442. {
  11443. tree ptr = build_fold_addr_expr (array);
  11444. int elemsize;
  11445. if (k)
  11446. {
  11447. arg = DECL_CHAIN (arg);
  11448. j++;
  11449. }
  11450. elemsize
  11451. = GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (TREE_TYPE (arg))));
  11452. tree t = build2 (MEM_REF, TREE_TYPE (arg), ptr,
  11453. build_int_cst (ptype, k * elemsize));
  11454. t = build2 (MODIFY_EXPR, TREE_TYPE (t), t, arg);
  11455. gimplify_and_add (t, &seq);
  11456. }
  11457. }
  11458. }
  11459. return seq;
  11460. }
  11461. /* Callback info for ipa_simd_modify_stmt_ops below. */
  11462. struct modify_stmt_info {
  11463. ipa_parm_adjustment_vec adjustments;
  11464. gimple stmt;
  11465. /* True if the parent statement was modified by
  11466. ipa_simd_modify_stmt_ops. */
  11467. bool modified;
  11468. };
  11469. /* Callback for walk_gimple_op.
  11470. Adjust operands from a given statement as specified in the
  11471. adjustments vector in the callback data. */
  11472. static tree
  11473. ipa_simd_modify_stmt_ops (tree *tp, int *walk_subtrees, void *data)
  11474. {
  11475. struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
  11476. struct modify_stmt_info *info = (struct modify_stmt_info *) wi->info;
  11477. tree *orig_tp = tp;
  11478. if (TREE_CODE (*tp) == ADDR_EXPR)
  11479. tp = &TREE_OPERAND (*tp, 0);
  11480. struct ipa_parm_adjustment *cand = NULL;
  11481. if (TREE_CODE (*tp) == PARM_DECL)
  11482. cand = ipa_get_adjustment_candidate (&tp, NULL, info->adjustments, true);
  11483. else
  11484. {
  11485. if (TYPE_P (*tp))
  11486. *walk_subtrees = 0;
  11487. }
  11488. tree repl = NULL_TREE;
  11489. if (cand)
  11490. repl = unshare_expr (cand->new_decl);
  11491. else
  11492. {
  11493. if (tp != orig_tp)
  11494. {
  11495. *walk_subtrees = 0;
  11496. bool modified = info->modified;
  11497. info->modified = false;
  11498. walk_tree (tp, ipa_simd_modify_stmt_ops, wi, wi->pset);
  11499. if (!info->modified)
  11500. {
  11501. info->modified = modified;
  11502. return NULL_TREE;
  11503. }
  11504. info->modified = modified;
  11505. repl = *tp;
  11506. }
  11507. else
  11508. return NULL_TREE;
  11509. }
  11510. if (tp != orig_tp)
  11511. {
  11512. repl = build_fold_addr_expr (repl);
  11513. gimple stmt;
  11514. if (is_gimple_debug (info->stmt))
  11515. {
  11516. tree vexpr = make_node (DEBUG_EXPR_DECL);
  11517. stmt = gimple_build_debug_source_bind (vexpr, repl, NULL);
  11518. DECL_ARTIFICIAL (vexpr) = 1;
  11519. TREE_TYPE (vexpr) = TREE_TYPE (repl);
  11520. DECL_MODE (vexpr) = TYPE_MODE (TREE_TYPE (repl));
  11521. repl = vexpr;
  11522. }
  11523. else
  11524. {
  11525. stmt = gimple_build_assign (make_ssa_name (TREE_TYPE (repl)), repl);
  11526. repl = gimple_assign_lhs (stmt);
  11527. }
  11528. gimple_stmt_iterator gsi = gsi_for_stmt (info->stmt);
  11529. gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
  11530. *orig_tp = repl;
  11531. }
  11532. else if (!useless_type_conversion_p (TREE_TYPE (*tp), TREE_TYPE (repl)))
  11533. {
  11534. tree vce = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (*tp), repl);
  11535. *tp = vce;
  11536. }
  11537. else
  11538. *tp = repl;
  11539. info->modified = true;
  11540. return NULL_TREE;
  11541. }
  11542. /* Traverse the function body and perform all modifications as
  11543. described in ADJUSTMENTS. At function return, ADJUSTMENTS will be
  11544. modified such that the replacement/reduction value will now be an
  11545. offset into the corresponding simd_array.
  11546. This function will replace all function argument uses with their
  11547. corresponding simd array elements, and ajust the return values
  11548. accordingly. */
  11549. static void
  11550. ipa_simd_modify_function_body (struct cgraph_node *node,
  11551. ipa_parm_adjustment_vec adjustments,
  11552. tree retval_array, tree iter)
  11553. {
  11554. basic_block bb;
  11555. unsigned int i, j, l;
  11556. /* Re-use the adjustments array, but this time use it to replace
  11557. every function argument use to an offset into the corresponding
  11558. simd_array. */
  11559. for (i = 0, j = 0; i < node->simdclone->nargs; ++i, ++j)
  11560. {
  11561. if (!node->simdclone->args[i].vector_arg)
  11562. continue;
  11563. tree basetype = TREE_TYPE (node->simdclone->args[i].orig_arg);
  11564. tree vectype = TREE_TYPE (node->simdclone->args[i].vector_arg);
  11565. adjustments[j].new_decl
  11566. = build4 (ARRAY_REF,
  11567. basetype,
  11568. node->simdclone->args[i].simd_array,
  11569. iter,
  11570. NULL_TREE, NULL_TREE);
  11571. if (adjustments[j].op == IPA_PARM_OP_NONE
  11572. && TYPE_VECTOR_SUBPARTS (vectype) < node->simdclone->simdlen)
  11573. j += node->simdclone->simdlen / TYPE_VECTOR_SUBPARTS (vectype) - 1;
  11574. }
  11575. l = adjustments.length ();
  11576. for (i = 1; i < num_ssa_names; i++)
  11577. {
  11578. tree name = ssa_name (i);
  11579. if (name
  11580. && SSA_NAME_VAR (name)
  11581. && TREE_CODE (SSA_NAME_VAR (name)) == PARM_DECL)
  11582. {
  11583. for (j = 0; j < l; j++)
  11584. if (SSA_NAME_VAR (name) == adjustments[j].base
  11585. && adjustments[j].new_decl)
  11586. {
  11587. tree base_var;
  11588. if (adjustments[j].new_ssa_base == NULL_TREE)
  11589. {
  11590. base_var
  11591. = copy_var_decl (adjustments[j].base,
  11592. DECL_NAME (adjustments[j].base),
  11593. TREE_TYPE (adjustments[j].base));
  11594. adjustments[j].new_ssa_base = base_var;
  11595. }
  11596. else
  11597. base_var = adjustments[j].new_ssa_base;
  11598. if (SSA_NAME_IS_DEFAULT_DEF (name))
  11599. {
  11600. bb = single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun));
  11601. gimple_stmt_iterator gsi = gsi_after_labels (bb);
  11602. tree new_decl = unshare_expr (adjustments[j].new_decl);
  11603. set_ssa_default_def (cfun, adjustments[j].base, NULL_TREE);
  11604. SET_SSA_NAME_VAR_OR_IDENTIFIER (name, base_var);
  11605. SSA_NAME_IS_DEFAULT_DEF (name) = 0;
  11606. gimple stmt = gimple_build_assign (name, new_decl);
  11607. gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
  11608. }
  11609. else
  11610. SET_SSA_NAME_VAR_OR_IDENTIFIER (name, base_var);
  11611. }
  11612. }
  11613. }
  11614. struct modify_stmt_info info;
  11615. info.adjustments = adjustments;
  11616. FOR_EACH_BB_FN (bb, DECL_STRUCT_FUNCTION (node->decl))
  11617. {
  11618. gimple_stmt_iterator gsi;
  11619. gsi = gsi_start_bb (bb);
  11620. while (!gsi_end_p (gsi))
  11621. {
  11622. gimple stmt = gsi_stmt (gsi);
  11623. info.stmt = stmt;
  11624. struct walk_stmt_info wi;
  11625. memset (&wi, 0, sizeof (wi));
  11626. info.modified = false;
  11627. wi.info = &info;
  11628. walk_gimple_op (stmt, ipa_simd_modify_stmt_ops, &wi);
  11629. if (greturn *return_stmt = dyn_cast <greturn *> (stmt))
  11630. {
  11631. tree retval = gimple_return_retval (return_stmt);
  11632. if (!retval)
  11633. {
  11634. gsi_remove (&gsi, true);
  11635. continue;
  11636. }
  11637. /* Replace `return foo' with `retval_array[iter] = foo'. */
  11638. tree ref = build4 (ARRAY_REF, TREE_TYPE (retval),
  11639. retval_array, iter, NULL, NULL);
  11640. stmt = gimple_build_assign (ref, retval);
  11641. gsi_replace (&gsi, stmt, true);
  11642. info.modified = true;
  11643. }
  11644. if (info.modified)
  11645. {
  11646. update_stmt (stmt);
  11647. if (maybe_clean_eh_stmt (stmt))
  11648. gimple_purge_dead_eh_edges (gimple_bb (stmt));
  11649. }
  11650. gsi_next (&gsi);
  11651. }
  11652. }
  11653. }
  11654. /* Adjust the argument types in NODE to their appropriate vector
  11655. counterparts. */
  11656. static void
  11657. simd_clone_adjust (struct cgraph_node *node)
  11658. {
  11659. push_cfun (DECL_STRUCT_FUNCTION (node->decl));
  11660. targetm.simd_clone.adjust (node);
  11661. tree retval = simd_clone_adjust_return_type (node);
  11662. ipa_parm_adjustment_vec adjustments
  11663. = simd_clone_adjust_argument_types (node);
  11664. push_gimplify_context ();
  11665. gimple_seq seq = simd_clone_init_simd_arrays (node, adjustments);
  11666. /* Adjust all uses of vector arguments accordingly. Adjust all
  11667. return values accordingly. */
  11668. tree iter = create_tmp_var (unsigned_type_node, "iter");
  11669. tree iter1 = make_ssa_name (iter);
  11670. tree iter2 = make_ssa_name (iter);
  11671. ipa_simd_modify_function_body (node, adjustments, retval, iter1);
  11672. /* Initialize the iteration variable. */
  11673. basic_block entry_bb = single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun));
  11674. basic_block body_bb = split_block_after_labels (entry_bb)->dest;
  11675. gimple_stmt_iterator gsi = gsi_after_labels (entry_bb);
  11676. /* Insert the SIMD array and iv initialization at function
  11677. entry. */
  11678. gsi_insert_seq_before (&gsi, seq, GSI_NEW_STMT);
  11679. pop_gimplify_context (NULL);
  11680. /* Create a new BB right before the original exit BB, to hold the
  11681. iteration increment and the condition/branch. */
  11682. basic_block orig_exit = EDGE_PRED (EXIT_BLOCK_PTR_FOR_FN (cfun), 0)->src;
  11683. basic_block incr_bb = create_empty_bb (orig_exit);
  11684. add_bb_to_loop (incr_bb, body_bb->loop_father);
  11685. /* The succ of orig_exit was EXIT_BLOCK_PTR_FOR_FN (cfun), with an empty
  11686. flag. Set it now to be a FALLTHRU_EDGE. */
  11687. gcc_assert (EDGE_COUNT (orig_exit->succs) == 1);
  11688. EDGE_SUCC (orig_exit, 0)->flags |= EDGE_FALLTHRU;
  11689. for (unsigned i = 0;
  11690. i < EDGE_COUNT (EXIT_BLOCK_PTR_FOR_FN (cfun)->preds); ++i)
  11691. {
  11692. edge e = EDGE_PRED (EXIT_BLOCK_PTR_FOR_FN (cfun), i);
  11693. redirect_edge_succ (e, incr_bb);
  11694. }
  11695. edge e = make_edge (incr_bb, EXIT_BLOCK_PTR_FOR_FN (cfun), 0);
  11696. e->probability = REG_BR_PROB_BASE;
  11697. gsi = gsi_last_bb (incr_bb);
  11698. gimple g = gimple_build_assign (iter2, PLUS_EXPR, iter1,
  11699. build_int_cst (unsigned_type_node, 1));
  11700. gsi_insert_after (&gsi, g, GSI_CONTINUE_LINKING);
  11701. /* Mostly annotate the loop for the vectorizer (the rest is done below). */
  11702. struct loop *loop = alloc_loop ();
  11703. cfun->has_force_vectorize_loops = true;
  11704. loop->safelen = node->simdclone->simdlen;
  11705. loop->force_vectorize = true;
  11706. loop->header = body_bb;
  11707. /* Branch around the body if the mask applies. */
  11708. if (node->simdclone->inbranch)
  11709. {
  11710. gimple_stmt_iterator gsi = gsi_last_bb (loop->header);
  11711. tree mask_array
  11712. = node->simdclone->args[node->simdclone->nargs - 1].simd_array;
  11713. tree mask = make_ssa_name (TREE_TYPE (TREE_TYPE (mask_array)));
  11714. tree aref = build4 (ARRAY_REF,
  11715. TREE_TYPE (TREE_TYPE (mask_array)),
  11716. mask_array, iter1,
  11717. NULL, NULL);
  11718. g = gimple_build_assign (mask, aref);
  11719. gsi_insert_after (&gsi, g, GSI_CONTINUE_LINKING);
  11720. int bitsize = GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (aref)));
  11721. if (!INTEGRAL_TYPE_P (TREE_TYPE (aref)))
  11722. {
  11723. aref = build1 (VIEW_CONVERT_EXPR,
  11724. build_nonstandard_integer_type (bitsize, 0), mask);
  11725. mask = make_ssa_name (TREE_TYPE (aref));
  11726. g = gimple_build_assign (mask, aref);
  11727. gsi_insert_after (&gsi, g, GSI_CONTINUE_LINKING);
  11728. }
  11729. g = gimple_build_cond (EQ_EXPR, mask, build_zero_cst (TREE_TYPE (mask)),
  11730. NULL, NULL);
  11731. gsi_insert_after (&gsi, g, GSI_CONTINUE_LINKING);
  11732. make_edge (loop->header, incr_bb, EDGE_TRUE_VALUE);
  11733. FALLTHRU_EDGE (loop->header)->flags = EDGE_FALSE_VALUE;
  11734. }
  11735. /* Generate the condition. */
  11736. g = gimple_build_cond (LT_EXPR,
  11737. iter2,
  11738. build_int_cst (unsigned_type_node,
  11739. node->simdclone->simdlen),
  11740. NULL, NULL);
  11741. gsi_insert_after (&gsi, g, GSI_CONTINUE_LINKING);
  11742. e = split_block (incr_bb, gsi_stmt (gsi));
  11743. basic_block latch_bb = e->dest;
  11744. basic_block new_exit_bb;
  11745. new_exit_bb = split_block (latch_bb, NULL)->dest;
  11746. loop->latch = latch_bb;
  11747. redirect_edge_succ (FALLTHRU_EDGE (latch_bb), body_bb);
  11748. make_edge (incr_bb, new_exit_bb, EDGE_FALSE_VALUE);
  11749. /* The successor of incr_bb is already pointing to latch_bb; just
  11750. change the flags.
  11751. make_edge (incr_bb, latch_bb, EDGE_TRUE_VALUE); */
  11752. FALLTHRU_EDGE (incr_bb)->flags = EDGE_TRUE_VALUE;
  11753. gphi *phi = create_phi_node (iter1, body_bb);
  11754. edge preheader_edge = find_edge (entry_bb, body_bb);
  11755. edge latch_edge = single_succ_edge (latch_bb);
  11756. add_phi_arg (phi, build_zero_cst (unsigned_type_node), preheader_edge,
  11757. UNKNOWN_LOCATION);
  11758. add_phi_arg (phi, iter2, latch_edge, UNKNOWN_LOCATION);
  11759. /* Generate the new return. */
  11760. gsi = gsi_last_bb (new_exit_bb);
  11761. if (retval
  11762. && TREE_CODE (retval) == VIEW_CONVERT_EXPR
  11763. && TREE_CODE (TREE_OPERAND (retval, 0)) == RESULT_DECL)
  11764. retval = TREE_OPERAND (retval, 0);
  11765. else if (retval)
  11766. {
  11767. retval = build1 (VIEW_CONVERT_EXPR,
  11768. TREE_TYPE (TREE_TYPE (node->decl)),
  11769. retval);
  11770. retval = force_gimple_operand_gsi (&gsi, retval, true, NULL,
  11771. false, GSI_CONTINUE_LINKING);
  11772. }
  11773. g = gimple_build_return (retval);
  11774. gsi_insert_after (&gsi, g, GSI_CONTINUE_LINKING);
  11775. /* Handle aligned clauses by replacing default defs of the aligned
  11776. uniform args with __builtin_assume_aligned (arg_N(D), alignment)
  11777. lhs. Handle linear by adding PHIs. */
  11778. for (unsigned i = 0; i < node->simdclone->nargs; i++)
  11779. if (node->simdclone->args[i].arg_type == SIMD_CLONE_ARG_TYPE_UNIFORM
  11780. && (TREE_ADDRESSABLE (node->simdclone->args[i].orig_arg)
  11781. || !is_gimple_reg_type
  11782. (TREE_TYPE (node->simdclone->args[i].orig_arg))))
  11783. {
  11784. tree orig_arg = node->simdclone->args[i].orig_arg;
  11785. if (is_gimple_reg_type (TREE_TYPE (orig_arg)))
  11786. iter1 = make_ssa_name (TREE_TYPE (orig_arg));
  11787. else
  11788. {
  11789. iter1 = create_tmp_var_raw (TREE_TYPE (orig_arg));
  11790. gimple_add_tmp_var (iter1);
  11791. }
  11792. gsi = gsi_after_labels (entry_bb);
  11793. g = gimple_build_assign (iter1, orig_arg);
  11794. gsi_insert_before (&gsi, g, GSI_NEW_STMT);
  11795. gsi = gsi_after_labels (body_bb);
  11796. g = gimple_build_assign (orig_arg, iter1);
  11797. gsi_insert_before (&gsi, g, GSI_NEW_STMT);
  11798. }
  11799. else if (node->simdclone->args[i].arg_type == SIMD_CLONE_ARG_TYPE_UNIFORM
  11800. && DECL_BY_REFERENCE (node->simdclone->args[i].orig_arg)
  11801. && TREE_CODE (TREE_TYPE (node->simdclone->args[i].orig_arg))
  11802. == REFERENCE_TYPE
  11803. && TREE_ADDRESSABLE
  11804. (TREE_TYPE (TREE_TYPE (node->simdclone->args[i].orig_arg))))
  11805. {
  11806. tree orig_arg = node->simdclone->args[i].orig_arg;
  11807. tree def = ssa_default_def (cfun, orig_arg);
  11808. if (def && !has_zero_uses (def))
  11809. {
  11810. iter1 = create_tmp_var_raw (TREE_TYPE (TREE_TYPE (orig_arg)));
  11811. gimple_add_tmp_var (iter1);
  11812. gsi = gsi_after_labels (entry_bb);
  11813. g = gimple_build_assign (iter1, build_simple_mem_ref (def));
  11814. gsi_insert_before (&gsi, g, GSI_NEW_STMT);
  11815. gsi = gsi_after_labels (body_bb);
  11816. g = gimple_build_assign (build_simple_mem_ref (def), iter1);
  11817. gsi_insert_before (&gsi, g, GSI_NEW_STMT);
  11818. }
  11819. }
  11820. else if (node->simdclone->args[i].alignment
  11821. && node->simdclone->args[i].arg_type
  11822. == SIMD_CLONE_ARG_TYPE_UNIFORM
  11823. && (node->simdclone->args[i].alignment
  11824. & (node->simdclone->args[i].alignment - 1)) == 0
  11825. && TREE_CODE (TREE_TYPE (node->simdclone->args[i].orig_arg))
  11826. == POINTER_TYPE)
  11827. {
  11828. unsigned int alignment = node->simdclone->args[i].alignment;
  11829. tree orig_arg = node->simdclone->args[i].orig_arg;
  11830. tree def = ssa_default_def (cfun, orig_arg);
  11831. if (def && !has_zero_uses (def))
  11832. {
  11833. tree fn = builtin_decl_explicit (BUILT_IN_ASSUME_ALIGNED);
  11834. gimple_seq seq = NULL;
  11835. bool need_cvt = false;
  11836. gcall *call
  11837. = gimple_build_call (fn, 2, def, size_int (alignment));
  11838. g = call;
  11839. if (!useless_type_conversion_p (TREE_TYPE (orig_arg),
  11840. ptr_type_node))
  11841. need_cvt = true;
  11842. tree t = make_ssa_name (need_cvt ? ptr_type_node : orig_arg);
  11843. gimple_call_set_lhs (g, t);
  11844. gimple_seq_add_stmt_without_update (&seq, g);
  11845. if (need_cvt)
  11846. {
  11847. t = make_ssa_name (orig_arg);
  11848. g = gimple_build_assign (t, NOP_EXPR, gimple_call_lhs (g));
  11849. gimple_seq_add_stmt_without_update (&seq, g);
  11850. }
  11851. gsi_insert_seq_on_edge_immediate
  11852. (single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun)), seq);
  11853. entry_bb = single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun));
  11854. int freq = compute_call_stmt_bb_frequency (current_function_decl,
  11855. entry_bb);
  11856. node->create_edge (cgraph_node::get_create (fn),
  11857. call, entry_bb->count, freq);
  11858. imm_use_iterator iter;
  11859. use_operand_p use_p;
  11860. gimple use_stmt;
  11861. tree repl = gimple_get_lhs (g);
  11862. FOR_EACH_IMM_USE_STMT (use_stmt, iter, def)
  11863. if (is_gimple_debug (use_stmt) || use_stmt == call)
  11864. continue;
  11865. else
  11866. FOR_EACH_IMM_USE_ON_STMT (use_p, iter)
  11867. SET_USE (use_p, repl);
  11868. }
  11869. }
  11870. else if (node->simdclone->args[i].arg_type
  11871. == SIMD_CLONE_ARG_TYPE_LINEAR_CONSTANT_STEP)
  11872. {
  11873. tree orig_arg = node->simdclone->args[i].orig_arg;
  11874. gcc_assert (INTEGRAL_TYPE_P (TREE_TYPE (orig_arg))
  11875. || POINTER_TYPE_P (TREE_TYPE (orig_arg)));
  11876. tree def = NULL_TREE;
  11877. if (TREE_ADDRESSABLE (orig_arg))
  11878. {
  11879. def = make_ssa_name (TREE_TYPE (orig_arg));
  11880. iter1 = make_ssa_name (TREE_TYPE (orig_arg));
  11881. iter2 = make_ssa_name (TREE_TYPE (orig_arg));
  11882. gsi = gsi_after_labels (entry_bb);
  11883. g = gimple_build_assign (def, orig_arg);
  11884. gsi_insert_before (&gsi, g, GSI_NEW_STMT);
  11885. }
  11886. else
  11887. {
  11888. def = ssa_default_def (cfun, orig_arg);
  11889. if (!def || has_zero_uses (def))
  11890. def = NULL_TREE;
  11891. else
  11892. {
  11893. iter1 = make_ssa_name (orig_arg);
  11894. iter2 = make_ssa_name (orig_arg);
  11895. }
  11896. }
  11897. if (def)
  11898. {
  11899. phi = create_phi_node (iter1, body_bb);
  11900. add_phi_arg (phi, def, preheader_edge, UNKNOWN_LOCATION);
  11901. add_phi_arg (phi, iter2, latch_edge, UNKNOWN_LOCATION);
  11902. enum tree_code code = INTEGRAL_TYPE_P (TREE_TYPE (orig_arg))
  11903. ? PLUS_EXPR : POINTER_PLUS_EXPR;
  11904. tree addtype = INTEGRAL_TYPE_P (TREE_TYPE (orig_arg))
  11905. ? TREE_TYPE (orig_arg) : sizetype;
  11906. tree addcst
  11907. = build_int_cst (addtype, node->simdclone->args[i].linear_step);
  11908. g = gimple_build_assign (iter2, code, iter1, addcst);
  11909. gsi = gsi_last_bb (incr_bb);
  11910. gsi_insert_before (&gsi, g, GSI_SAME_STMT);
  11911. imm_use_iterator iter;
  11912. use_operand_p use_p;
  11913. gimple use_stmt;
  11914. if (TREE_ADDRESSABLE (orig_arg))
  11915. {
  11916. gsi = gsi_after_labels (body_bb);
  11917. g = gimple_build_assign (orig_arg, iter1);
  11918. gsi_insert_before (&gsi, g, GSI_NEW_STMT);
  11919. }
  11920. else
  11921. FOR_EACH_IMM_USE_STMT (use_stmt, iter, def)
  11922. if (use_stmt == phi)
  11923. continue;
  11924. else
  11925. FOR_EACH_IMM_USE_ON_STMT (use_p, iter)
  11926. SET_USE (use_p, iter1);
  11927. }
  11928. }
  11929. calculate_dominance_info (CDI_DOMINATORS);
  11930. add_loop (loop, loop->header->loop_father);
  11931. update_ssa (TODO_update_ssa);
  11932. pop_cfun ();
  11933. }
  11934. /* If the function in NODE is tagged as an elemental SIMD function,
  11935. create the appropriate SIMD clones. */
  11936. static void
  11937. expand_simd_clones (struct cgraph_node *node)
  11938. {
  11939. tree attr = lookup_attribute ("omp declare simd",
  11940. DECL_ATTRIBUTES (node->decl));
  11941. if (attr == NULL_TREE
  11942. || node->global.inlined_to
  11943. || lookup_attribute ("noclone", DECL_ATTRIBUTES (node->decl)))
  11944. return;
  11945. /* Ignore
  11946. #pragma omp declare simd
  11947. extern int foo ();
  11948. in C, there we don't know the argument types at all. */
  11949. if (!node->definition
  11950. && TYPE_ARG_TYPES (TREE_TYPE (node->decl)) == NULL_TREE)
  11951. return;
  11952. do
  11953. {
  11954. /* Start with parsing the "omp declare simd" attribute(s). */
  11955. bool inbranch_clause_specified;
  11956. struct cgraph_simd_clone *clone_info
  11957. = simd_clone_clauses_extract (node, TREE_VALUE (attr),
  11958. &inbranch_clause_specified);
  11959. if (clone_info == NULL)
  11960. continue;
  11961. int orig_simdlen = clone_info->simdlen;
  11962. tree base_type = simd_clone_compute_base_data_type (node, clone_info);
  11963. /* The target can return 0 (no simd clones should be created),
  11964. 1 (just one ISA of simd clones should be created) or higher
  11965. count of ISA variants. In that case, clone_info is initialized
  11966. for the first ISA variant. */
  11967. int count
  11968. = targetm.simd_clone.compute_vecsize_and_simdlen (node, clone_info,
  11969. base_type, 0);
  11970. if (count == 0)
  11971. continue;
  11972. /* Loop over all COUNT ISA variants, and if !INBRANCH_CLAUSE_SPECIFIED,
  11973. also create one inbranch and one !inbranch clone of it. */
  11974. for (int i = 0; i < count * 2; i++)
  11975. {
  11976. struct cgraph_simd_clone *clone = clone_info;
  11977. if (inbranch_clause_specified && (i & 1) != 0)
  11978. continue;
  11979. if (i != 0)
  11980. {
  11981. clone = simd_clone_struct_alloc (clone_info->nargs
  11982. + ((i & 1) != 0));
  11983. simd_clone_struct_copy (clone, clone_info);
  11984. /* Undo changes targetm.simd_clone.compute_vecsize_and_simdlen
  11985. and simd_clone_adjust_argument_types did to the first
  11986. clone's info. */
  11987. clone->nargs -= clone_info->inbranch;
  11988. clone->simdlen = orig_simdlen;
  11989. /* And call the target hook again to get the right ISA. */
  11990. targetm.simd_clone.compute_vecsize_and_simdlen (node, clone,
  11991. base_type,
  11992. i / 2);
  11993. if ((i & 1) != 0)
  11994. clone->inbranch = 1;
  11995. }
  11996. /* simd_clone_mangle might fail if such a clone has been created
  11997. already. */
  11998. tree id = simd_clone_mangle (node, clone);
  11999. if (id == NULL_TREE)
  12000. continue;
  12001. /* Only when we are sure we want to create the clone actually
  12002. clone the function (or definitions) or create another
  12003. extern FUNCTION_DECL (for prototypes without definitions). */
  12004. struct cgraph_node *n = simd_clone_create (node);
  12005. if (n == NULL)
  12006. continue;
  12007. n->simdclone = clone;
  12008. clone->origin = node;
  12009. clone->next_clone = NULL;
  12010. if (node->simd_clones == NULL)
  12011. {
  12012. clone->prev_clone = n;
  12013. node->simd_clones = n;
  12014. }
  12015. else
  12016. {
  12017. clone->prev_clone = node->simd_clones->simdclone->prev_clone;
  12018. clone->prev_clone->simdclone->next_clone = n;
  12019. node->simd_clones->simdclone->prev_clone = n;
  12020. }
  12021. symtab->change_decl_assembler_name (n->decl, id);
  12022. /* And finally adjust the return type, parameters and for
  12023. definitions also function body. */
  12024. if (node->definition)
  12025. simd_clone_adjust (n);
  12026. else
  12027. {
  12028. simd_clone_adjust_return_type (n);
  12029. simd_clone_adjust_argument_types (n);
  12030. }
  12031. }
  12032. }
  12033. while ((attr = lookup_attribute ("omp declare simd", TREE_CHAIN (attr))));
  12034. }
  12035. /* Entry point for IPA simd clone creation pass. */
  12036. static unsigned int
  12037. ipa_omp_simd_clone (void)
  12038. {
  12039. struct cgraph_node *node;
  12040. FOR_EACH_FUNCTION (node)
  12041. expand_simd_clones (node);
  12042. return 0;
  12043. }
  12044. namespace {
  12045. const pass_data pass_data_omp_simd_clone =
  12046. {
  12047. SIMPLE_IPA_PASS, /* type */
  12048. "simdclone", /* name */
  12049. OPTGROUP_NONE, /* optinfo_flags */
  12050. TV_NONE, /* tv_id */
  12051. ( PROP_ssa | PROP_cfg ), /* properties_required */
  12052. 0, /* properties_provided */
  12053. 0, /* properties_destroyed */
  12054. 0, /* todo_flags_start */
  12055. 0, /* todo_flags_finish */
  12056. };
  12057. class pass_omp_simd_clone : public simple_ipa_opt_pass
  12058. {
  12059. public:
  12060. pass_omp_simd_clone(gcc::context *ctxt)
  12061. : simple_ipa_opt_pass(pass_data_omp_simd_clone, ctxt)
  12062. {}
  12063. /* opt_pass methods: */
  12064. virtual bool gate (function *);
  12065. virtual unsigned int execute (function *) { return ipa_omp_simd_clone (); }
  12066. };
  12067. bool
  12068. pass_omp_simd_clone::gate (function *)
  12069. {
  12070. return ((flag_openmp || flag_openmp_simd
  12071. || flag_cilkplus
  12072. || (in_lto_p && !flag_wpa))
  12073. && (targetm.simd_clone.compute_vecsize_and_simdlen != NULL));
  12074. }
  12075. } // anon namespace
  12076. simple_ipa_opt_pass *
  12077. make_pass_omp_simd_clone (gcc::context *ctxt)
  12078. {
  12079. return new pass_omp_simd_clone (ctxt);
  12080. }
  12081. /* Helper function for omp_finish_file routine. Takes decls from V_DECLS and
  12082. adds their addresses and sizes to constructor-vector V_CTOR. */
  12083. static void
  12084. add_decls_addresses_to_decl_constructor (vec<tree, va_gc> *v_decls,
  12085. vec<constructor_elt, va_gc> *v_ctor)
  12086. {
  12087. unsigned len = vec_safe_length (v_decls);
  12088. for (unsigned i = 0; i < len; i++)
  12089. {
  12090. tree it = (*v_decls)[i];
  12091. bool is_function = TREE_CODE (it) != VAR_DECL;
  12092. CONSTRUCTOR_APPEND_ELT (v_ctor, NULL_TREE, build_fold_addr_expr (it));
  12093. if (!is_function)
  12094. CONSTRUCTOR_APPEND_ELT (v_ctor, NULL_TREE,
  12095. fold_convert (const_ptr_type_node,
  12096. DECL_SIZE_UNIT (it)));
  12097. }
  12098. }
  12099. /* Create new symbols containing (address, size) pairs for global variables,
  12100. marked with "omp declare target" attribute, as well as addresses for the
  12101. functions, which are outlined offloading regions. */
  12102. void
  12103. omp_finish_file (void)
  12104. {
  12105. unsigned num_funcs = vec_safe_length (offload_funcs);
  12106. unsigned num_vars = vec_safe_length (offload_vars);
  12107. if (num_funcs == 0 && num_vars == 0)
  12108. return;
  12109. if (targetm_common.have_named_sections)
  12110. {
  12111. vec<constructor_elt, va_gc> *v_f, *v_v;
  12112. vec_alloc (v_f, num_funcs);
  12113. vec_alloc (v_v, num_vars * 2);
  12114. add_decls_addresses_to_decl_constructor (offload_funcs, v_f);
  12115. add_decls_addresses_to_decl_constructor (offload_vars, v_v);
  12116. tree vars_decl_type = build_array_type_nelts (pointer_sized_int_node,
  12117. num_vars * 2);
  12118. tree funcs_decl_type = build_array_type_nelts (pointer_sized_int_node,
  12119. num_funcs);
  12120. TYPE_ALIGN (vars_decl_type) = TYPE_ALIGN (pointer_sized_int_node);
  12121. TYPE_ALIGN (funcs_decl_type) = TYPE_ALIGN (pointer_sized_int_node);
  12122. tree ctor_v = build_constructor (vars_decl_type, v_v);
  12123. tree ctor_f = build_constructor (funcs_decl_type, v_f);
  12124. TREE_CONSTANT (ctor_v) = TREE_CONSTANT (ctor_f) = 1;
  12125. TREE_STATIC (ctor_v) = TREE_STATIC (ctor_f) = 1;
  12126. tree funcs_decl = build_decl (UNKNOWN_LOCATION, VAR_DECL,
  12127. get_identifier (".offload_func_table"),
  12128. funcs_decl_type);
  12129. tree vars_decl = build_decl (UNKNOWN_LOCATION, VAR_DECL,
  12130. get_identifier (".offload_var_table"),
  12131. vars_decl_type);
  12132. TREE_STATIC (funcs_decl) = TREE_STATIC (vars_decl) = 1;
  12133. /* Do not align tables more than TYPE_ALIGN (pointer_sized_int_node),
  12134. otherwise a joint table in a binary will contain padding between
  12135. tables from multiple object files. */
  12136. DECL_USER_ALIGN (funcs_decl) = DECL_USER_ALIGN (vars_decl) = 1;
  12137. DECL_ALIGN (funcs_decl) = TYPE_ALIGN (funcs_decl_type);
  12138. DECL_ALIGN (vars_decl) = TYPE_ALIGN (vars_decl_type);
  12139. DECL_INITIAL (funcs_decl) = ctor_f;
  12140. DECL_INITIAL (vars_decl) = ctor_v;
  12141. set_decl_section_name (funcs_decl, OFFLOAD_FUNC_TABLE_SECTION_NAME);
  12142. set_decl_section_name (vars_decl, OFFLOAD_VAR_TABLE_SECTION_NAME);
  12143. varpool_node::finalize_decl (vars_decl);
  12144. varpool_node::finalize_decl (funcs_decl);
  12145. }
  12146. else
  12147. {
  12148. for (unsigned i = 0; i < num_funcs; i++)
  12149. {
  12150. tree it = (*offload_funcs)[i];
  12151. targetm.record_offload_symbol (it);
  12152. }
  12153. for (unsigned i = 0; i < num_vars; i++)
  12154. {
  12155. tree it = (*offload_vars)[i];
  12156. targetm.record_offload_symbol (it);
  12157. }
  12158. }
  12159. }
  12160. #include "gt-omp-low.h"