trans-openmp.c 135 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508
  1. /* OpenMP directive translation -- generate GCC trees from gfc_code.
  2. Copyright (C) 2005-2015 Free Software Foundation, Inc.
  3. Contributed by Jakub Jelinek <jakub@redhat.com>
  4. This file is part of GCC.
  5. GCC is free software; you can redistribute it and/or modify it under
  6. the terms of the GNU General Public License as published by the Free
  7. Software Foundation; either version 3, or (at your option) any later
  8. version.
  9. GCC is distributed in the hope that it will be useful, but WITHOUT ANY
  10. WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11. FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  12. for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with GCC; see the file COPYING3. If not see
  15. <http://www.gnu.org/licenses/>. */
  16. #include "config.h"
  17. #include "system.h"
  18. #include "coretypes.h"
  19. #include "hash-set.h"
  20. #include "machmode.h"
  21. #include "vec.h"
  22. #include "double-int.h"
  23. #include "input.h"
  24. #include "alias.h"
  25. #include "symtab.h"
  26. #include "options.h"
  27. #include "wide-int.h"
  28. #include "inchash.h"
  29. #include "tree.h"
  30. #include "fold-const.h"
  31. #include "gimple-expr.h"
  32. #include "gimplify.h" /* For create_tmp_var_raw. */
  33. #include "stringpool.h"
  34. #include "gfortran.h"
  35. #include "diagnostic-core.h" /* For internal_error. */
  36. #include "trans.h"
  37. #include "trans-stmt.h"
  38. #include "trans-types.h"
  39. #include "trans-array.h"
  40. #include "trans-const.h"
  41. #include "arith.h"
  42. #include "omp-low.h"
  43. #include "gomp-constants.h"
  44. int ompws_flags;
  45. /* True if OpenMP should privatize what this DECL points to rather
  46. than the DECL itself. */
  47. bool
  48. gfc_omp_privatize_by_reference (const_tree decl)
  49. {
  50. tree type = TREE_TYPE (decl);
  51. if (TREE_CODE (type) == REFERENCE_TYPE
  52. && (!DECL_ARTIFICIAL (decl) || TREE_CODE (decl) == PARM_DECL))
  53. return true;
  54. if (TREE_CODE (type) == POINTER_TYPE)
  55. {
  56. /* Array POINTER/ALLOCATABLE have aggregate types, all user variables
  57. that have POINTER_TYPE type and aren't scalar pointers, scalar
  58. allocatables, Cray pointees or C pointers are supposed to be
  59. privatized by reference. */
  60. if (GFC_DECL_GET_SCALAR_POINTER (decl)
  61. || GFC_DECL_GET_SCALAR_ALLOCATABLE (decl)
  62. || GFC_DECL_CRAY_POINTEE (decl)
  63. || VOID_TYPE_P (TREE_TYPE (TREE_TYPE (decl))))
  64. return false;
  65. if (!DECL_ARTIFICIAL (decl)
  66. && TREE_CODE (TREE_TYPE (type)) != FUNCTION_TYPE)
  67. return true;
  68. /* Some arrays are expanded as DECL_ARTIFICIAL pointers
  69. by the frontend. */
  70. if (DECL_LANG_SPECIFIC (decl)
  71. && GFC_DECL_SAVED_DESCRIPTOR (decl))
  72. return true;
  73. }
  74. return false;
  75. }
  76. /* True if OpenMP sharing attribute of DECL is predetermined. */
  77. enum omp_clause_default_kind
  78. gfc_omp_predetermined_sharing (tree decl)
  79. {
  80. /* Associate names preserve the association established during ASSOCIATE.
  81. As they are implemented either as pointers to the selector or array
  82. descriptor and shouldn't really change in the ASSOCIATE region,
  83. this decl can be either shared or firstprivate. If it is a pointer,
  84. use firstprivate, as it is cheaper that way, otherwise make it shared. */
  85. if (GFC_DECL_ASSOCIATE_VAR_P (decl))
  86. {
  87. if (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE)
  88. return OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;
  89. else
  90. return OMP_CLAUSE_DEFAULT_SHARED;
  91. }
  92. if (DECL_ARTIFICIAL (decl)
  93. && ! GFC_DECL_RESULT (decl)
  94. && ! (DECL_LANG_SPECIFIC (decl)
  95. && GFC_DECL_SAVED_DESCRIPTOR (decl)))
  96. return OMP_CLAUSE_DEFAULT_SHARED;
  97. /* Cray pointees shouldn't be listed in any clauses and should be
  98. gimplified to dereference of the corresponding Cray pointer.
  99. Make them all private, so that they are emitted in the debug
  100. information. */
  101. if (GFC_DECL_CRAY_POINTEE (decl))
  102. return OMP_CLAUSE_DEFAULT_PRIVATE;
  103. /* Assumed-size arrays are predetermined shared. */
  104. if (TREE_CODE (decl) == PARM_DECL
  105. && GFC_ARRAY_TYPE_P (TREE_TYPE (decl))
  106. && GFC_TYPE_ARRAY_AKIND (TREE_TYPE (decl)) == GFC_ARRAY_UNKNOWN
  107. && GFC_TYPE_ARRAY_UBOUND (TREE_TYPE (decl),
  108. GFC_TYPE_ARRAY_RANK (TREE_TYPE (decl)) - 1)
  109. == NULL)
  110. return OMP_CLAUSE_DEFAULT_SHARED;
  111. /* Dummy procedures aren't considered variables by OpenMP, thus are
  112. disallowed in OpenMP clauses. They are represented as PARM_DECLs
  113. in the middle-end, so return OMP_CLAUSE_DEFAULT_FIRSTPRIVATE here
  114. to avoid complaining about their uses with default(none). */
  115. if (TREE_CODE (decl) == PARM_DECL
  116. && TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
  117. && TREE_CODE (TREE_TYPE (TREE_TYPE (decl))) == FUNCTION_TYPE)
  118. return OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;
  119. /* COMMON and EQUIVALENCE decls are shared. They
  120. are only referenced through DECL_VALUE_EXPR of the variables
  121. contained in them. If those are privatized, they will not be
  122. gimplified to the COMMON or EQUIVALENCE decls. */
  123. if (GFC_DECL_COMMON_OR_EQUIV (decl) && ! DECL_HAS_VALUE_EXPR_P (decl))
  124. return OMP_CLAUSE_DEFAULT_SHARED;
  125. if (GFC_DECL_RESULT (decl) && ! DECL_HAS_VALUE_EXPR_P (decl))
  126. return OMP_CLAUSE_DEFAULT_SHARED;
  127. /* These are either array or derived parameters, or vtables.
  128. In the former cases, the OpenMP standard doesn't consider them to be
  129. variables at all (they can't be redefined), but they can nevertheless appear
  130. in parallel/task regions and for default(none) purposes treat them as shared.
  131. For vtables likely the same handling is desirable. */
  132. if (TREE_CODE (decl) == VAR_DECL
  133. && TREE_READONLY (decl)
  134. && TREE_STATIC (decl))
  135. return OMP_CLAUSE_DEFAULT_SHARED;
  136. return OMP_CLAUSE_DEFAULT_UNSPECIFIED;
  137. }
  138. /* Return decl that should be used when reporting DEFAULT(NONE)
  139. diagnostics. */
  140. tree
  141. gfc_omp_report_decl (tree decl)
  142. {
  143. if (DECL_ARTIFICIAL (decl)
  144. && DECL_LANG_SPECIFIC (decl)
  145. && GFC_DECL_SAVED_DESCRIPTOR (decl))
  146. return GFC_DECL_SAVED_DESCRIPTOR (decl);
  147. return decl;
  148. }
  149. /* Return true if TYPE has any allocatable components. */
  150. static bool
  151. gfc_has_alloc_comps (tree type, tree decl)
  152. {
  153. tree field, ftype;
  154. if (POINTER_TYPE_P (type))
  155. {
  156. if (GFC_DECL_GET_SCALAR_ALLOCATABLE (decl))
  157. type = TREE_TYPE (type);
  158. else if (GFC_DECL_GET_SCALAR_POINTER (decl))
  159. return false;
  160. }
  161. if (GFC_DESCRIPTOR_TYPE_P (type) || GFC_ARRAY_TYPE_P (type))
  162. type = gfc_get_element_type (type);
  163. if (TREE_CODE (type) != RECORD_TYPE)
  164. return false;
  165. for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
  166. {
  167. ftype = TREE_TYPE (field);
  168. if (GFC_DECL_GET_SCALAR_ALLOCATABLE (field))
  169. return true;
  170. if (GFC_DESCRIPTOR_TYPE_P (ftype)
  171. && GFC_TYPE_ARRAY_AKIND (ftype) == GFC_ARRAY_ALLOCATABLE)
  172. return true;
  173. if (gfc_has_alloc_comps (ftype, field))
  174. return true;
  175. }
  176. return false;
  177. }
  178. /* Return true if DECL in private clause needs
  179. OMP_CLAUSE_PRIVATE_OUTER_REF on the private clause. */
  180. bool
  181. gfc_omp_private_outer_ref (tree decl)
  182. {
  183. tree type = TREE_TYPE (decl);
  184. if (GFC_DESCRIPTOR_TYPE_P (type)
  185. && GFC_TYPE_ARRAY_AKIND (type) == GFC_ARRAY_ALLOCATABLE)
  186. return true;
  187. if (GFC_DECL_GET_SCALAR_ALLOCATABLE (decl))
  188. return true;
  189. if (gfc_omp_privatize_by_reference (decl))
  190. type = TREE_TYPE (type);
  191. if (gfc_has_alloc_comps (type, decl))
  192. return true;
  193. return false;
  194. }
  195. /* Callback for gfc_omp_unshare_expr. */
  196. static tree
  197. gfc_omp_unshare_expr_r (tree *tp, int *walk_subtrees, void *)
  198. {
  199. tree t = *tp;
  200. enum tree_code code = TREE_CODE (t);
  201. /* Stop at types, decls, constants like copy_tree_r. */
  202. if (TREE_CODE_CLASS (code) == tcc_type
  203. || TREE_CODE_CLASS (code) == tcc_declaration
  204. || TREE_CODE_CLASS (code) == tcc_constant
  205. || code == BLOCK)
  206. *walk_subtrees = 0;
  207. else if (handled_component_p (t)
  208. || TREE_CODE (t) == MEM_REF)
  209. {
  210. *tp = unshare_expr (t);
  211. *walk_subtrees = 0;
  212. }
  213. return NULL_TREE;
  214. }
  215. /* Unshare in expr anything that the FE which normally doesn't
  216. care much about tree sharing (because during gimplification
  217. everything is unshared) could cause problems with tree sharing
  218. at omp-low.c time. */
  219. static tree
  220. gfc_omp_unshare_expr (tree expr)
  221. {
  222. walk_tree (&expr, gfc_omp_unshare_expr_r, NULL, NULL);
  223. return expr;
  224. }
  225. enum walk_alloc_comps
  226. {
  227. WALK_ALLOC_COMPS_DTOR,
  228. WALK_ALLOC_COMPS_DEFAULT_CTOR,
  229. WALK_ALLOC_COMPS_COPY_CTOR
  230. };
  231. /* Handle allocatable components in OpenMP clauses. */
  232. static tree
  233. gfc_walk_alloc_comps (tree decl, tree dest, tree var,
  234. enum walk_alloc_comps kind)
  235. {
  236. stmtblock_t block, tmpblock;
  237. tree type = TREE_TYPE (decl), then_b, tem, field;
  238. gfc_init_block (&block);
  239. if (GFC_ARRAY_TYPE_P (type) || GFC_DESCRIPTOR_TYPE_P (type))
  240. {
  241. if (GFC_DESCRIPTOR_TYPE_P (type))
  242. {
  243. gfc_init_block (&tmpblock);
  244. tem = gfc_full_array_size (&tmpblock, decl,
  245. GFC_TYPE_ARRAY_RANK (type));
  246. then_b = gfc_finish_block (&tmpblock);
  247. gfc_add_expr_to_block (&block, gfc_omp_unshare_expr (then_b));
  248. tem = gfc_omp_unshare_expr (tem);
  249. tem = fold_build2_loc (input_location, MINUS_EXPR,
  250. gfc_array_index_type, tem,
  251. gfc_index_one_node);
  252. }
  253. else
  254. {
  255. if (!TYPE_DOMAIN (type)
  256. || TYPE_MAX_VALUE (TYPE_DOMAIN (type)) == NULL_TREE
  257. || TYPE_MIN_VALUE (TYPE_DOMAIN (type)) == error_mark_node
  258. || TYPE_MAX_VALUE (TYPE_DOMAIN (type)) == error_mark_node)
  259. {
  260. tem = fold_build2 (EXACT_DIV_EXPR, sizetype,
  261. TYPE_SIZE_UNIT (type),
  262. TYPE_SIZE_UNIT (TREE_TYPE (type)));
  263. tem = size_binop (MINUS_EXPR, tem, size_one_node);
  264. }
  265. else
  266. tem = array_type_nelts (type);
  267. tem = fold_convert (gfc_array_index_type, tem);
  268. }
  269. tree nelems = gfc_evaluate_now (tem, &block);
  270. tree index = gfc_create_var (gfc_array_index_type, "S");
  271. gfc_init_block (&tmpblock);
  272. tem = gfc_conv_array_data (decl);
  273. tree declvar = build_fold_indirect_ref_loc (input_location, tem);
  274. tree declvref = gfc_build_array_ref (declvar, index, NULL);
  275. tree destvar, destvref = NULL_TREE;
  276. if (dest)
  277. {
  278. tem = gfc_conv_array_data (dest);
  279. destvar = build_fold_indirect_ref_loc (input_location, tem);
  280. destvref = gfc_build_array_ref (destvar, index, NULL);
  281. }
  282. gfc_add_expr_to_block (&tmpblock,
  283. gfc_walk_alloc_comps (declvref, destvref,
  284. var, kind));
  285. gfc_loopinfo loop;
  286. gfc_init_loopinfo (&loop);
  287. loop.dimen = 1;
  288. loop.from[0] = gfc_index_zero_node;
  289. loop.loopvar[0] = index;
  290. loop.to[0] = nelems;
  291. gfc_trans_scalarizing_loops (&loop, &tmpblock);
  292. gfc_add_block_to_block (&block, &loop.pre);
  293. return gfc_finish_block (&block);
  294. }
  295. else if (GFC_DECL_GET_SCALAR_ALLOCATABLE (var))
  296. {
  297. decl = build_fold_indirect_ref_loc (input_location, decl);
  298. if (dest)
  299. dest = build_fold_indirect_ref_loc (input_location, dest);
  300. type = TREE_TYPE (decl);
  301. }
  302. gcc_assert (TREE_CODE (type) == RECORD_TYPE);
  303. for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
  304. {
  305. tree ftype = TREE_TYPE (field);
  306. tree declf, destf = NULL_TREE;
  307. bool has_alloc_comps = gfc_has_alloc_comps (ftype, field);
  308. if ((!GFC_DESCRIPTOR_TYPE_P (ftype)
  309. || GFC_TYPE_ARRAY_AKIND (ftype) != GFC_ARRAY_ALLOCATABLE)
  310. && !GFC_DECL_GET_SCALAR_ALLOCATABLE (field)
  311. && !has_alloc_comps)
  312. continue;
  313. declf = fold_build3_loc (input_location, COMPONENT_REF, ftype,
  314. decl, field, NULL_TREE);
  315. if (dest)
  316. destf = fold_build3_loc (input_location, COMPONENT_REF, ftype,
  317. dest, field, NULL_TREE);
  318. tem = NULL_TREE;
  319. switch (kind)
  320. {
  321. case WALK_ALLOC_COMPS_DTOR:
  322. break;
  323. case WALK_ALLOC_COMPS_DEFAULT_CTOR:
  324. if (GFC_DESCRIPTOR_TYPE_P (ftype)
  325. && GFC_TYPE_ARRAY_AKIND (ftype) == GFC_ARRAY_ALLOCATABLE)
  326. {
  327. gfc_add_modify (&block, unshare_expr (destf),
  328. unshare_expr (declf));
  329. tem = gfc_duplicate_allocatable_nocopy
  330. (destf, declf, ftype,
  331. GFC_TYPE_ARRAY_RANK (ftype));
  332. }
  333. else if (GFC_DECL_GET_SCALAR_ALLOCATABLE (field))
  334. tem = gfc_duplicate_allocatable_nocopy (destf, declf, ftype, 0);
  335. break;
  336. case WALK_ALLOC_COMPS_COPY_CTOR:
  337. if (GFC_DESCRIPTOR_TYPE_P (ftype)
  338. && GFC_TYPE_ARRAY_AKIND (ftype) == GFC_ARRAY_ALLOCATABLE)
  339. tem = gfc_duplicate_allocatable (destf, declf, ftype,
  340. GFC_TYPE_ARRAY_RANK (ftype));
  341. else if (GFC_DECL_GET_SCALAR_ALLOCATABLE (field))
  342. tem = gfc_duplicate_allocatable (destf, declf, ftype, 0);
  343. break;
  344. }
  345. if (tem)
  346. gfc_add_expr_to_block (&block, gfc_omp_unshare_expr (tem));
  347. if (has_alloc_comps)
  348. {
  349. gfc_init_block (&tmpblock);
  350. gfc_add_expr_to_block (&tmpblock,
  351. gfc_walk_alloc_comps (declf, destf,
  352. field, kind));
  353. then_b = gfc_finish_block (&tmpblock);
  354. if (GFC_DESCRIPTOR_TYPE_P (ftype)
  355. && GFC_TYPE_ARRAY_AKIND (ftype) == GFC_ARRAY_ALLOCATABLE)
  356. tem = gfc_conv_descriptor_data_get (unshare_expr (declf));
  357. else if (GFC_DECL_GET_SCALAR_ALLOCATABLE (field))
  358. tem = unshare_expr (declf);
  359. else
  360. tem = NULL_TREE;
  361. if (tem)
  362. {
  363. tem = fold_convert (pvoid_type_node, tem);
  364. tem = fold_build2_loc (input_location, NE_EXPR,
  365. boolean_type_node, tem,
  366. null_pointer_node);
  367. then_b = build3_loc (input_location, COND_EXPR, void_type_node,
  368. tem, then_b,
  369. build_empty_stmt (input_location));
  370. }
  371. gfc_add_expr_to_block (&block, then_b);
  372. }
  373. if (kind == WALK_ALLOC_COMPS_DTOR)
  374. {
  375. if (GFC_DESCRIPTOR_TYPE_P (ftype)
  376. && GFC_TYPE_ARRAY_AKIND (ftype) == GFC_ARRAY_ALLOCATABLE)
  377. {
  378. tem = gfc_trans_dealloc_allocated (unshare_expr (declf),
  379. false, NULL);
  380. gfc_add_expr_to_block (&block, gfc_omp_unshare_expr (tem));
  381. }
  382. else if (GFC_DECL_GET_SCALAR_ALLOCATABLE (field))
  383. {
  384. tem = gfc_call_free (unshare_expr (declf));
  385. gfc_add_expr_to_block (&block, gfc_omp_unshare_expr (tem));
  386. }
  387. }
  388. }
  389. return gfc_finish_block (&block);
  390. }
  391. /* Return code to initialize DECL with its default constructor, or
  392. NULL if there's nothing to do. */
  393. tree
  394. gfc_omp_clause_default_ctor (tree clause, tree decl, tree outer)
  395. {
  396. tree type = TREE_TYPE (decl), size, ptr, cond, then_b, else_b;
  397. stmtblock_t block, cond_block;
  398. gcc_assert (OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_PRIVATE
  399. || OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_LASTPRIVATE
  400. || OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_LINEAR
  401. || OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_REDUCTION);
  402. if ((! GFC_DESCRIPTOR_TYPE_P (type)
  403. || GFC_TYPE_ARRAY_AKIND (type) != GFC_ARRAY_ALLOCATABLE)
  404. && !GFC_DECL_GET_SCALAR_ALLOCATABLE (OMP_CLAUSE_DECL (clause)))
  405. {
  406. if (gfc_has_alloc_comps (type, OMP_CLAUSE_DECL (clause)))
  407. {
  408. gcc_assert (outer);
  409. gfc_start_block (&block);
  410. tree tem = gfc_walk_alloc_comps (outer, decl,
  411. OMP_CLAUSE_DECL (clause),
  412. WALK_ALLOC_COMPS_DEFAULT_CTOR);
  413. gfc_add_expr_to_block (&block, tem);
  414. return gfc_finish_block (&block);
  415. }
  416. return NULL_TREE;
  417. }
  418. gcc_assert (outer != NULL_TREE);
  419. /* Allocatable arrays and scalars in PRIVATE clauses need to be set to
  420. "not currently allocated" allocation status if outer
  421. array is "not currently allocated", otherwise should be allocated. */
  422. gfc_start_block (&block);
  423. gfc_init_block (&cond_block);
  424. if (GFC_DESCRIPTOR_TYPE_P (type))
  425. {
  426. gfc_add_modify (&cond_block, decl, outer);
  427. tree rank = gfc_rank_cst[GFC_TYPE_ARRAY_RANK (type) - 1];
  428. size = gfc_conv_descriptor_ubound_get (decl, rank);
  429. size = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
  430. size,
  431. gfc_conv_descriptor_lbound_get (decl, rank));
  432. size = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
  433. size, gfc_index_one_node);
  434. if (GFC_TYPE_ARRAY_RANK (type) > 1)
  435. size = fold_build2_loc (input_location, MULT_EXPR,
  436. gfc_array_index_type, size,
  437. gfc_conv_descriptor_stride_get (decl, rank));
  438. tree esize = fold_convert (gfc_array_index_type,
  439. TYPE_SIZE_UNIT (gfc_get_element_type (type)));
  440. size = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
  441. size, esize);
  442. size = unshare_expr (size);
  443. size = gfc_evaluate_now (fold_convert (size_type_node, size),
  444. &cond_block);
  445. }
  446. else
  447. size = fold_convert (size_type_node, TYPE_SIZE_UNIT (TREE_TYPE (type)));
  448. ptr = gfc_create_var (pvoid_type_node, NULL);
  449. gfc_allocate_using_malloc (&cond_block, ptr, size, NULL_TREE);
  450. if (GFC_DESCRIPTOR_TYPE_P (type))
  451. gfc_conv_descriptor_data_set (&cond_block, unshare_expr (decl), ptr);
  452. else
  453. gfc_add_modify (&cond_block, unshare_expr (decl),
  454. fold_convert (TREE_TYPE (decl), ptr));
  455. if (gfc_has_alloc_comps (type, OMP_CLAUSE_DECL (clause)))
  456. {
  457. tree tem = gfc_walk_alloc_comps (outer, decl,
  458. OMP_CLAUSE_DECL (clause),
  459. WALK_ALLOC_COMPS_DEFAULT_CTOR);
  460. gfc_add_expr_to_block (&cond_block, tem);
  461. }
  462. then_b = gfc_finish_block (&cond_block);
  463. /* Reduction clause requires allocated ALLOCATABLE. */
  464. if (OMP_CLAUSE_CODE (clause) != OMP_CLAUSE_REDUCTION)
  465. {
  466. gfc_init_block (&cond_block);
  467. if (GFC_DESCRIPTOR_TYPE_P (type))
  468. gfc_conv_descriptor_data_set (&cond_block, unshare_expr (decl),
  469. null_pointer_node);
  470. else
  471. gfc_add_modify (&cond_block, unshare_expr (decl),
  472. build_zero_cst (TREE_TYPE (decl)));
  473. else_b = gfc_finish_block (&cond_block);
  474. tree tem = fold_convert (pvoid_type_node,
  475. GFC_DESCRIPTOR_TYPE_P (type)
  476. ? gfc_conv_descriptor_data_get (outer) : outer);
  477. tem = unshare_expr (tem);
  478. cond = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
  479. tem, null_pointer_node);
  480. gfc_add_expr_to_block (&block,
  481. build3_loc (input_location, COND_EXPR,
  482. void_type_node, cond, then_b,
  483. else_b));
  484. }
  485. else
  486. gfc_add_expr_to_block (&block, then_b);
  487. return gfc_finish_block (&block);
  488. }
  489. /* Build and return code for a copy constructor from SRC to DEST. */
  490. tree
  491. gfc_omp_clause_copy_ctor (tree clause, tree dest, tree src)
  492. {
  493. tree type = TREE_TYPE (dest), ptr, size, call;
  494. tree cond, then_b, else_b;
  495. stmtblock_t block, cond_block;
  496. gcc_assert (OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_FIRSTPRIVATE
  497. || OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_LINEAR);
  498. if ((! GFC_DESCRIPTOR_TYPE_P (type)
  499. || GFC_TYPE_ARRAY_AKIND (type) != GFC_ARRAY_ALLOCATABLE)
  500. && !GFC_DECL_GET_SCALAR_ALLOCATABLE (OMP_CLAUSE_DECL (clause)))
  501. {
  502. if (gfc_has_alloc_comps (type, OMP_CLAUSE_DECL (clause)))
  503. {
  504. gfc_start_block (&block);
  505. gfc_add_modify (&block, dest, src);
  506. tree tem = gfc_walk_alloc_comps (src, dest, OMP_CLAUSE_DECL (clause),
  507. WALK_ALLOC_COMPS_COPY_CTOR);
  508. gfc_add_expr_to_block (&block, tem);
  509. return gfc_finish_block (&block);
  510. }
  511. else
  512. return build2_v (MODIFY_EXPR, dest, src);
  513. }
  514. /* Allocatable arrays in FIRSTPRIVATE clauses need to be allocated
  515. and copied from SRC. */
  516. gfc_start_block (&block);
  517. gfc_init_block (&cond_block);
  518. gfc_add_modify (&cond_block, dest, src);
  519. if (GFC_DESCRIPTOR_TYPE_P (type))
  520. {
  521. tree rank = gfc_rank_cst[GFC_TYPE_ARRAY_RANK (type) - 1];
  522. size = gfc_conv_descriptor_ubound_get (dest, rank);
  523. size = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
  524. size,
  525. gfc_conv_descriptor_lbound_get (dest, rank));
  526. size = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
  527. size, gfc_index_one_node);
  528. if (GFC_TYPE_ARRAY_RANK (type) > 1)
  529. size = fold_build2_loc (input_location, MULT_EXPR,
  530. gfc_array_index_type, size,
  531. gfc_conv_descriptor_stride_get (dest, rank));
  532. tree esize = fold_convert (gfc_array_index_type,
  533. TYPE_SIZE_UNIT (gfc_get_element_type (type)));
  534. size = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
  535. size, esize);
  536. size = unshare_expr (size);
  537. size = gfc_evaluate_now (fold_convert (size_type_node, size),
  538. &cond_block);
  539. }
  540. else
  541. size = fold_convert (size_type_node, TYPE_SIZE_UNIT (TREE_TYPE (type)));
  542. ptr = gfc_create_var (pvoid_type_node, NULL);
  543. gfc_allocate_using_malloc (&cond_block, ptr, size, NULL_TREE);
  544. if (GFC_DESCRIPTOR_TYPE_P (type))
  545. gfc_conv_descriptor_data_set (&cond_block, unshare_expr (dest), ptr);
  546. else
  547. gfc_add_modify (&cond_block, unshare_expr (dest),
  548. fold_convert (TREE_TYPE (dest), ptr));
  549. tree srcptr = GFC_DESCRIPTOR_TYPE_P (type)
  550. ? gfc_conv_descriptor_data_get (src) : src;
  551. srcptr = unshare_expr (srcptr);
  552. srcptr = fold_convert (pvoid_type_node, srcptr);
  553. call = build_call_expr_loc (input_location,
  554. builtin_decl_explicit (BUILT_IN_MEMCPY), 3, ptr,
  555. srcptr, size);
  556. gfc_add_expr_to_block (&cond_block, fold_convert (void_type_node, call));
  557. if (gfc_has_alloc_comps (type, OMP_CLAUSE_DECL (clause)))
  558. {
  559. tree tem = gfc_walk_alloc_comps (src, dest,
  560. OMP_CLAUSE_DECL (clause),
  561. WALK_ALLOC_COMPS_COPY_CTOR);
  562. gfc_add_expr_to_block (&cond_block, tem);
  563. }
  564. then_b = gfc_finish_block (&cond_block);
  565. gfc_init_block (&cond_block);
  566. if (GFC_DESCRIPTOR_TYPE_P (type))
  567. gfc_conv_descriptor_data_set (&cond_block, unshare_expr (dest),
  568. null_pointer_node);
  569. else
  570. gfc_add_modify (&cond_block, unshare_expr (dest),
  571. build_zero_cst (TREE_TYPE (dest)));
  572. else_b = gfc_finish_block (&cond_block);
  573. cond = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
  574. unshare_expr (srcptr), null_pointer_node);
  575. gfc_add_expr_to_block (&block,
  576. build3_loc (input_location, COND_EXPR,
  577. void_type_node, cond, then_b, else_b));
  578. return gfc_finish_block (&block);
  579. }
  580. /* Similarly, except use an intrinsic or pointer assignment operator
  581. instead. */
  582. tree
  583. gfc_omp_clause_assign_op (tree clause, tree dest, tree src)
  584. {
  585. tree type = TREE_TYPE (dest), ptr, size, call, nonalloc;
  586. tree cond, then_b, else_b;
  587. stmtblock_t block, cond_block, cond_block2, inner_block;
  588. if ((! GFC_DESCRIPTOR_TYPE_P (type)
  589. || GFC_TYPE_ARRAY_AKIND (type) != GFC_ARRAY_ALLOCATABLE)
  590. && !GFC_DECL_GET_SCALAR_ALLOCATABLE (OMP_CLAUSE_DECL (clause)))
  591. {
  592. if (gfc_has_alloc_comps (type, OMP_CLAUSE_DECL (clause)))
  593. {
  594. gfc_start_block (&block);
  595. /* First dealloc any allocatable components in DEST. */
  596. tree tem = gfc_walk_alloc_comps (dest, NULL_TREE,
  597. OMP_CLAUSE_DECL (clause),
  598. WALK_ALLOC_COMPS_DTOR);
  599. gfc_add_expr_to_block (&block, tem);
  600. /* Then copy over toplevel data. */
  601. gfc_add_modify (&block, dest, src);
  602. /* Finally allocate any allocatable components and copy. */
  603. tem = gfc_walk_alloc_comps (src, dest, OMP_CLAUSE_DECL (clause),
  604. WALK_ALLOC_COMPS_COPY_CTOR);
  605. gfc_add_expr_to_block (&block, tem);
  606. return gfc_finish_block (&block);
  607. }
  608. else
  609. return build2_v (MODIFY_EXPR, dest, src);
  610. }
  611. gfc_start_block (&block);
  612. if (gfc_has_alloc_comps (type, OMP_CLAUSE_DECL (clause)))
  613. {
  614. then_b = gfc_walk_alloc_comps (dest, NULL_TREE, OMP_CLAUSE_DECL (clause),
  615. WALK_ALLOC_COMPS_DTOR);
  616. tree tem = fold_convert (pvoid_type_node,
  617. GFC_DESCRIPTOR_TYPE_P (type)
  618. ? gfc_conv_descriptor_data_get (dest) : dest);
  619. tem = unshare_expr (tem);
  620. cond = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
  621. tem, null_pointer_node);
  622. tem = build3_loc (input_location, COND_EXPR, void_type_node, cond,
  623. then_b, build_empty_stmt (input_location));
  624. gfc_add_expr_to_block (&block, tem);
  625. }
  626. gfc_init_block (&cond_block);
  627. if (GFC_DESCRIPTOR_TYPE_P (type))
  628. {
  629. tree rank = gfc_rank_cst[GFC_TYPE_ARRAY_RANK (type) - 1];
  630. size = gfc_conv_descriptor_ubound_get (src, rank);
  631. size = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
  632. size,
  633. gfc_conv_descriptor_lbound_get (src, rank));
  634. size = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
  635. size, gfc_index_one_node);
  636. if (GFC_TYPE_ARRAY_RANK (type) > 1)
  637. size = fold_build2_loc (input_location, MULT_EXPR,
  638. gfc_array_index_type, size,
  639. gfc_conv_descriptor_stride_get (src, rank));
  640. tree esize = fold_convert (gfc_array_index_type,
  641. TYPE_SIZE_UNIT (gfc_get_element_type (type)));
  642. size = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
  643. size, esize);
  644. size = unshare_expr (size);
  645. size = gfc_evaluate_now (fold_convert (size_type_node, size),
  646. &cond_block);
  647. }
  648. else
  649. size = fold_convert (size_type_node, TYPE_SIZE_UNIT (TREE_TYPE (type)));
  650. ptr = gfc_create_var (pvoid_type_node, NULL);
  651. tree destptr = GFC_DESCRIPTOR_TYPE_P (type)
  652. ? gfc_conv_descriptor_data_get (dest) : dest;
  653. destptr = unshare_expr (destptr);
  654. destptr = fold_convert (pvoid_type_node, destptr);
  655. gfc_add_modify (&cond_block, ptr, destptr);
  656. nonalloc = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
  657. destptr, null_pointer_node);
  658. cond = nonalloc;
  659. if (GFC_DESCRIPTOR_TYPE_P (type))
  660. {
  661. int i;
  662. for (i = 0; i < GFC_TYPE_ARRAY_RANK (type); i++)
  663. {
  664. tree rank = gfc_rank_cst[i];
  665. tree tem = gfc_conv_descriptor_ubound_get (src, rank);
  666. tem = fold_build2_loc (input_location, MINUS_EXPR,
  667. gfc_array_index_type, tem,
  668. gfc_conv_descriptor_lbound_get (src, rank));
  669. tem = fold_build2_loc (input_location, PLUS_EXPR,
  670. gfc_array_index_type, tem,
  671. gfc_conv_descriptor_lbound_get (dest, rank));
  672. tem = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
  673. tem, gfc_conv_descriptor_ubound_get (dest,
  674. rank));
  675. cond = fold_build2_loc (input_location, TRUTH_ORIF_EXPR,
  676. boolean_type_node, cond, tem);
  677. }
  678. }
  679. gfc_init_block (&cond_block2);
  680. if (GFC_DESCRIPTOR_TYPE_P (type))
  681. {
  682. gfc_init_block (&inner_block);
  683. gfc_allocate_using_malloc (&inner_block, ptr, size, NULL_TREE);
  684. then_b = gfc_finish_block (&inner_block);
  685. gfc_init_block (&inner_block);
  686. gfc_add_modify (&inner_block, ptr,
  687. gfc_call_realloc (&inner_block, ptr, size));
  688. else_b = gfc_finish_block (&inner_block);
  689. gfc_add_expr_to_block (&cond_block2,
  690. build3_loc (input_location, COND_EXPR,
  691. void_type_node,
  692. unshare_expr (nonalloc),
  693. then_b, else_b));
  694. gfc_add_modify (&cond_block2, dest, src);
  695. gfc_conv_descriptor_data_set (&cond_block2, unshare_expr (dest), ptr);
  696. }
  697. else
  698. {
  699. gfc_allocate_using_malloc (&cond_block2, ptr, size, NULL_TREE);
  700. gfc_add_modify (&cond_block2, unshare_expr (dest),
  701. fold_convert (type, ptr));
  702. }
  703. then_b = gfc_finish_block (&cond_block2);
  704. else_b = build_empty_stmt (input_location);
  705. gfc_add_expr_to_block (&cond_block,
  706. build3_loc (input_location, COND_EXPR,
  707. void_type_node, unshare_expr (cond),
  708. then_b, else_b));
  709. tree srcptr = GFC_DESCRIPTOR_TYPE_P (type)
  710. ? gfc_conv_descriptor_data_get (src) : src;
  711. srcptr = unshare_expr (srcptr);
  712. srcptr = fold_convert (pvoid_type_node, srcptr);
  713. call = build_call_expr_loc (input_location,
  714. builtin_decl_explicit (BUILT_IN_MEMCPY), 3, ptr,
  715. srcptr, size);
  716. gfc_add_expr_to_block (&cond_block, fold_convert (void_type_node, call));
  717. if (gfc_has_alloc_comps (type, OMP_CLAUSE_DECL (clause)))
  718. {
  719. tree tem = gfc_walk_alloc_comps (src, dest,
  720. OMP_CLAUSE_DECL (clause),
  721. WALK_ALLOC_COMPS_COPY_CTOR);
  722. gfc_add_expr_to_block (&cond_block, tem);
  723. }
  724. then_b = gfc_finish_block (&cond_block);
  725. if (OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_COPYIN)
  726. {
  727. gfc_init_block (&cond_block);
  728. if (GFC_DESCRIPTOR_TYPE_P (type))
  729. gfc_add_expr_to_block (&cond_block,
  730. gfc_trans_dealloc_allocated (unshare_expr (dest),
  731. false, NULL));
  732. else
  733. {
  734. destptr = gfc_evaluate_now (destptr, &cond_block);
  735. gfc_add_expr_to_block (&cond_block, gfc_call_free (destptr));
  736. gfc_add_modify (&cond_block, unshare_expr (dest),
  737. build_zero_cst (TREE_TYPE (dest)));
  738. }
  739. else_b = gfc_finish_block (&cond_block);
  740. cond = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
  741. unshare_expr (srcptr), null_pointer_node);
  742. gfc_add_expr_to_block (&block,
  743. build3_loc (input_location, COND_EXPR,
  744. void_type_node, cond,
  745. then_b, else_b));
  746. }
  747. else
  748. gfc_add_expr_to_block (&block, then_b);
  749. return gfc_finish_block (&block);
  750. }
  751. static void
  752. gfc_omp_linear_clause_add_loop (stmtblock_t *block, tree dest, tree src,
  753. tree add, tree nelems)
  754. {
  755. stmtblock_t tmpblock;
  756. tree desta, srca, index = gfc_create_var (gfc_array_index_type, "S");
  757. nelems = gfc_evaluate_now (nelems, block);
  758. gfc_init_block (&tmpblock);
  759. if (TREE_CODE (TREE_TYPE (dest)) == ARRAY_TYPE)
  760. {
  761. desta = gfc_build_array_ref (dest, index, NULL);
  762. srca = gfc_build_array_ref (src, index, NULL);
  763. }
  764. else
  765. {
  766. gcc_assert (POINTER_TYPE_P (TREE_TYPE (dest)));
  767. tree idx = fold_build2 (MULT_EXPR, sizetype,
  768. fold_convert (sizetype, index),
  769. TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (dest))));
  770. desta = build_fold_indirect_ref (fold_build2 (POINTER_PLUS_EXPR,
  771. TREE_TYPE (dest), dest,
  772. idx));
  773. srca = build_fold_indirect_ref (fold_build2 (POINTER_PLUS_EXPR,
  774. TREE_TYPE (src), src,
  775. idx));
  776. }
  777. gfc_add_modify (&tmpblock, desta,
  778. fold_build2 (PLUS_EXPR, TREE_TYPE (desta),
  779. srca, add));
  780. gfc_loopinfo loop;
  781. gfc_init_loopinfo (&loop);
  782. loop.dimen = 1;
  783. loop.from[0] = gfc_index_zero_node;
  784. loop.loopvar[0] = index;
  785. loop.to[0] = nelems;
  786. gfc_trans_scalarizing_loops (&loop, &tmpblock);
  787. gfc_add_block_to_block (block, &loop.pre);
  788. }
  789. /* Build and return code for a constructor of DEST that initializes
  790. it to SRC plus ADD (ADD is scalar integer). */
  791. tree
  792. gfc_omp_clause_linear_ctor (tree clause, tree dest, tree src, tree add)
  793. {
  794. tree type = TREE_TYPE (dest), ptr, size, nelems = NULL_TREE;
  795. stmtblock_t block;
  796. gcc_assert (OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_LINEAR);
  797. gfc_start_block (&block);
  798. add = gfc_evaluate_now (add, &block);
  799. if ((! GFC_DESCRIPTOR_TYPE_P (type)
  800. || GFC_TYPE_ARRAY_AKIND (type) != GFC_ARRAY_ALLOCATABLE)
  801. && !GFC_DECL_GET_SCALAR_ALLOCATABLE (OMP_CLAUSE_DECL (clause)))
  802. {
  803. gcc_assert (TREE_CODE (type) == ARRAY_TYPE);
  804. if (!TYPE_DOMAIN (type)
  805. || TYPE_MAX_VALUE (TYPE_DOMAIN (type)) == NULL_TREE
  806. || TYPE_MIN_VALUE (TYPE_DOMAIN (type)) == error_mark_node
  807. || TYPE_MAX_VALUE (TYPE_DOMAIN (type)) == error_mark_node)
  808. {
  809. nelems = fold_build2 (EXACT_DIV_EXPR, sizetype,
  810. TYPE_SIZE_UNIT (type),
  811. TYPE_SIZE_UNIT (TREE_TYPE (type)));
  812. nelems = size_binop (MINUS_EXPR, nelems, size_one_node);
  813. }
  814. else
  815. nelems = array_type_nelts (type);
  816. nelems = fold_convert (gfc_array_index_type, nelems);
  817. gfc_omp_linear_clause_add_loop (&block, dest, src, add, nelems);
  818. return gfc_finish_block (&block);
  819. }
  820. /* Allocatable arrays in LINEAR clauses need to be allocated
  821. and copied from SRC. */
  822. gfc_add_modify (&block, dest, src);
  823. if (GFC_DESCRIPTOR_TYPE_P (type))
  824. {
  825. tree rank = gfc_rank_cst[GFC_TYPE_ARRAY_RANK (type) - 1];
  826. size = gfc_conv_descriptor_ubound_get (dest, rank);
  827. size = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
  828. size,
  829. gfc_conv_descriptor_lbound_get (dest, rank));
  830. size = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
  831. size, gfc_index_one_node);
  832. if (GFC_TYPE_ARRAY_RANK (type) > 1)
  833. size = fold_build2_loc (input_location, MULT_EXPR,
  834. gfc_array_index_type, size,
  835. gfc_conv_descriptor_stride_get (dest, rank));
  836. tree esize = fold_convert (gfc_array_index_type,
  837. TYPE_SIZE_UNIT (gfc_get_element_type (type)));
  838. nelems = gfc_evaluate_now (unshare_expr (size), &block);
  839. size = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
  840. nelems, unshare_expr (esize));
  841. size = gfc_evaluate_now (fold_convert (size_type_node, size),
  842. &block);
  843. nelems = fold_build2_loc (input_location, MINUS_EXPR,
  844. gfc_array_index_type, nelems,
  845. gfc_index_one_node);
  846. }
  847. else
  848. size = fold_convert (size_type_node, TYPE_SIZE_UNIT (TREE_TYPE (type)));
  849. ptr = gfc_create_var (pvoid_type_node, NULL);
  850. gfc_allocate_using_malloc (&block, ptr, size, NULL_TREE);
  851. if (GFC_DESCRIPTOR_TYPE_P (type))
  852. {
  853. gfc_conv_descriptor_data_set (&block, unshare_expr (dest), ptr);
  854. tree etype = gfc_get_element_type (type);
  855. ptr = fold_convert (build_pointer_type (etype), ptr);
  856. tree srcptr = gfc_conv_descriptor_data_get (unshare_expr (src));
  857. srcptr = fold_convert (build_pointer_type (etype), srcptr);
  858. gfc_omp_linear_clause_add_loop (&block, ptr, srcptr, add, nelems);
  859. }
  860. else
  861. {
  862. gfc_add_modify (&block, unshare_expr (dest),
  863. fold_convert (TREE_TYPE (dest), ptr));
  864. ptr = fold_convert (TREE_TYPE (dest), ptr);
  865. tree dstm = build_fold_indirect_ref (ptr);
  866. tree srcm = build_fold_indirect_ref (unshare_expr (src));
  867. gfc_add_modify (&block, dstm,
  868. fold_build2 (PLUS_EXPR, TREE_TYPE (add), srcm, add));
  869. }
  870. return gfc_finish_block (&block);
  871. }
  872. /* Build and return code destructing DECL. Return NULL if nothing
  873. to be done. */
  874. tree
  875. gfc_omp_clause_dtor (tree clause, tree decl)
  876. {
  877. tree type = TREE_TYPE (decl), tem;
  878. if ((! GFC_DESCRIPTOR_TYPE_P (type)
  879. || GFC_TYPE_ARRAY_AKIND (type) != GFC_ARRAY_ALLOCATABLE)
  880. && !GFC_DECL_GET_SCALAR_ALLOCATABLE (OMP_CLAUSE_DECL (clause)))
  881. {
  882. if (gfc_has_alloc_comps (type, OMP_CLAUSE_DECL (clause)))
  883. return gfc_walk_alloc_comps (decl, NULL_TREE,
  884. OMP_CLAUSE_DECL (clause),
  885. WALK_ALLOC_COMPS_DTOR);
  886. return NULL_TREE;
  887. }
  888. if (GFC_DESCRIPTOR_TYPE_P (type))
  889. /* Allocatable arrays in FIRSTPRIVATE/LASTPRIVATE etc. clauses need
  890. to be deallocated if they were allocated. */
  891. tem = gfc_trans_dealloc_allocated (decl, false, NULL);
  892. else
  893. tem = gfc_call_free (decl);
  894. tem = gfc_omp_unshare_expr (tem);
  895. if (gfc_has_alloc_comps (type, OMP_CLAUSE_DECL (clause)))
  896. {
  897. stmtblock_t block;
  898. tree then_b;
  899. gfc_init_block (&block);
  900. gfc_add_expr_to_block (&block,
  901. gfc_walk_alloc_comps (decl, NULL_TREE,
  902. OMP_CLAUSE_DECL (clause),
  903. WALK_ALLOC_COMPS_DTOR));
  904. gfc_add_expr_to_block (&block, tem);
  905. then_b = gfc_finish_block (&block);
  906. tem = fold_convert (pvoid_type_node,
  907. GFC_DESCRIPTOR_TYPE_P (type)
  908. ? gfc_conv_descriptor_data_get (decl) : decl);
  909. tem = unshare_expr (tem);
  910. tree cond = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
  911. tem, null_pointer_node);
  912. tem = build3_loc (input_location, COND_EXPR, void_type_node, cond,
  913. then_b, build_empty_stmt (input_location));
  914. }
  915. return tem;
  916. }
  917. void
  918. gfc_omp_finish_clause (tree c, gimple_seq *pre_p)
  919. {
  920. if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_MAP)
  921. return;
  922. tree decl = OMP_CLAUSE_DECL (c);
  923. tree c2 = NULL_TREE, c3 = NULL_TREE, c4 = NULL_TREE;
  924. if (POINTER_TYPE_P (TREE_TYPE (decl)))
  925. {
  926. if (!gfc_omp_privatize_by_reference (decl)
  927. && !GFC_DECL_GET_SCALAR_POINTER (decl)
  928. && !GFC_DECL_GET_SCALAR_ALLOCATABLE (decl)
  929. && !GFC_DECL_CRAY_POINTEE (decl)
  930. && !GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (TREE_TYPE (decl))))
  931. return;
  932. tree orig_decl = decl;
  933. c4 = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_MAP);
  934. OMP_CLAUSE_SET_MAP_KIND (c4, GOMP_MAP_POINTER);
  935. OMP_CLAUSE_DECL (c4) = decl;
  936. OMP_CLAUSE_SIZE (c4) = size_int (0);
  937. decl = build_fold_indirect_ref (decl);
  938. OMP_CLAUSE_DECL (c) = decl;
  939. OMP_CLAUSE_SIZE (c) = NULL_TREE;
  940. if (TREE_CODE (TREE_TYPE (orig_decl)) == REFERENCE_TYPE
  941. && (GFC_DECL_GET_SCALAR_POINTER (orig_decl)
  942. || GFC_DECL_GET_SCALAR_ALLOCATABLE (orig_decl)))
  943. {
  944. c3 = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_MAP);
  945. OMP_CLAUSE_SET_MAP_KIND (c3, GOMP_MAP_POINTER);
  946. OMP_CLAUSE_DECL (c3) = unshare_expr (decl);
  947. OMP_CLAUSE_SIZE (c3) = size_int (0);
  948. decl = build_fold_indirect_ref (decl);
  949. OMP_CLAUSE_DECL (c) = decl;
  950. }
  951. }
  952. if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl)))
  953. {
  954. stmtblock_t block;
  955. gfc_start_block (&block);
  956. tree type = TREE_TYPE (decl);
  957. tree ptr = gfc_conv_descriptor_data_get (decl);
  958. ptr = fold_convert (build_pointer_type (char_type_node), ptr);
  959. ptr = build_fold_indirect_ref (ptr);
  960. OMP_CLAUSE_DECL (c) = ptr;
  961. c2 = build_omp_clause (input_location, OMP_CLAUSE_MAP);
  962. OMP_CLAUSE_SET_MAP_KIND (c2, GOMP_MAP_TO_PSET);
  963. OMP_CLAUSE_DECL (c2) = decl;
  964. OMP_CLAUSE_SIZE (c2) = TYPE_SIZE_UNIT (type);
  965. c3 = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_MAP);
  966. OMP_CLAUSE_SET_MAP_KIND (c3, GOMP_MAP_POINTER);
  967. OMP_CLAUSE_DECL (c3) = gfc_conv_descriptor_data_get (decl);
  968. OMP_CLAUSE_SIZE (c3) = size_int (0);
  969. tree size = create_tmp_var (gfc_array_index_type);
  970. tree elemsz = TYPE_SIZE_UNIT (gfc_get_element_type (type));
  971. elemsz = fold_convert (gfc_array_index_type, elemsz);
  972. if (GFC_TYPE_ARRAY_AKIND (type) == GFC_ARRAY_POINTER
  973. || GFC_TYPE_ARRAY_AKIND (type) == GFC_ARRAY_POINTER_CONT)
  974. {
  975. stmtblock_t cond_block;
  976. tree tem, then_b, else_b, zero, cond;
  977. gfc_init_block (&cond_block);
  978. tem = gfc_full_array_size (&cond_block, decl,
  979. GFC_TYPE_ARRAY_RANK (type));
  980. gfc_add_modify (&cond_block, size, tem);
  981. gfc_add_modify (&cond_block, size,
  982. fold_build2 (MULT_EXPR, gfc_array_index_type,
  983. size, elemsz));
  984. then_b = gfc_finish_block (&cond_block);
  985. gfc_init_block (&cond_block);
  986. zero = build_int_cst (gfc_array_index_type, 0);
  987. gfc_add_modify (&cond_block, size, zero);
  988. else_b = gfc_finish_block (&cond_block);
  989. tem = gfc_conv_descriptor_data_get (decl);
  990. tem = fold_convert (pvoid_type_node, tem);
  991. cond = fold_build2_loc (input_location, NE_EXPR,
  992. boolean_type_node, tem, null_pointer_node);
  993. gfc_add_expr_to_block (&block, build3_loc (input_location, COND_EXPR,
  994. void_type_node, cond,
  995. then_b, else_b));
  996. }
  997. else
  998. {
  999. gfc_add_modify (&block, size,
  1000. gfc_full_array_size (&block, decl,
  1001. GFC_TYPE_ARRAY_RANK (type)));
  1002. gfc_add_modify (&block, size,
  1003. fold_build2 (MULT_EXPR, gfc_array_index_type,
  1004. size, elemsz));
  1005. }
  1006. OMP_CLAUSE_SIZE (c) = size;
  1007. tree stmt = gfc_finish_block (&block);
  1008. gimplify_and_add (stmt, pre_p);
  1009. }
  1010. tree last = c;
  1011. if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
  1012. OMP_CLAUSE_SIZE (c)
  1013. = DECL_P (decl) ? DECL_SIZE_UNIT (decl)
  1014. : TYPE_SIZE_UNIT (TREE_TYPE (decl));
  1015. if (c2)
  1016. {
  1017. OMP_CLAUSE_CHAIN (c2) = OMP_CLAUSE_CHAIN (last);
  1018. OMP_CLAUSE_CHAIN (last) = c2;
  1019. last = c2;
  1020. }
  1021. if (c3)
  1022. {
  1023. OMP_CLAUSE_CHAIN (c3) = OMP_CLAUSE_CHAIN (last);
  1024. OMP_CLAUSE_CHAIN (last) = c3;
  1025. last = c3;
  1026. }
  1027. if (c4)
  1028. {
  1029. OMP_CLAUSE_CHAIN (c4) = OMP_CLAUSE_CHAIN (last);
  1030. OMP_CLAUSE_CHAIN (last) = c4;
  1031. last = c4;
  1032. }
  1033. }
  1034. /* Return true if DECL's DECL_VALUE_EXPR (if any) should be
  1035. disregarded in OpenMP construct, because it is going to be
  1036. remapped during OpenMP lowering. SHARED is true if DECL
  1037. is going to be shared, false if it is going to be privatized. */
  1038. bool
  1039. gfc_omp_disregard_value_expr (tree decl, bool shared)
  1040. {
  1041. if (GFC_DECL_COMMON_OR_EQUIV (decl)
  1042. && DECL_HAS_VALUE_EXPR_P (decl))
  1043. {
  1044. tree value = DECL_VALUE_EXPR (decl);
  1045. if (TREE_CODE (value) == COMPONENT_REF
  1046. && TREE_CODE (TREE_OPERAND (value, 0)) == VAR_DECL
  1047. && GFC_DECL_COMMON_OR_EQUIV (TREE_OPERAND (value, 0)))
  1048. {
  1049. /* If variable in COMMON or EQUIVALENCE is privatized, return
  1050. true, as just that variable is supposed to be privatized,
  1051. not the whole COMMON or whole EQUIVALENCE.
  1052. For shared variables in COMMON or EQUIVALENCE, let them be
  1053. gimplified to DECL_VALUE_EXPR, so that for multiple shared vars
  1054. from the same COMMON or EQUIVALENCE just one sharing of the
  1055. whole COMMON or EQUIVALENCE is enough. */
  1056. return ! shared;
  1057. }
  1058. }
  1059. if (GFC_DECL_RESULT (decl) && DECL_HAS_VALUE_EXPR_P (decl))
  1060. return ! shared;
  1061. return false;
  1062. }
  1063. /* Return true if DECL that is shared iff SHARED is true should
  1064. be put into OMP_CLAUSE_PRIVATE with OMP_CLAUSE_PRIVATE_DEBUG
  1065. flag set. */
  1066. bool
  1067. gfc_omp_private_debug_clause (tree decl, bool shared)
  1068. {
  1069. if (GFC_DECL_CRAY_POINTEE (decl))
  1070. return true;
  1071. if (GFC_DECL_COMMON_OR_EQUIV (decl)
  1072. && DECL_HAS_VALUE_EXPR_P (decl))
  1073. {
  1074. tree value = DECL_VALUE_EXPR (decl);
  1075. if (TREE_CODE (value) == COMPONENT_REF
  1076. && TREE_CODE (TREE_OPERAND (value, 0)) == VAR_DECL
  1077. && GFC_DECL_COMMON_OR_EQUIV (TREE_OPERAND (value, 0)))
  1078. return shared;
  1079. }
  1080. return false;
  1081. }
  1082. /* Register language specific type size variables as potentially OpenMP
  1083. firstprivate variables. */
  1084. void
  1085. gfc_omp_firstprivatize_type_sizes (struct gimplify_omp_ctx *ctx, tree type)
  1086. {
  1087. if (GFC_ARRAY_TYPE_P (type) || GFC_DESCRIPTOR_TYPE_P (type))
  1088. {
  1089. int r;
  1090. gcc_assert (TYPE_LANG_SPECIFIC (type) != NULL);
  1091. for (r = 0; r < GFC_TYPE_ARRAY_RANK (type); r++)
  1092. {
  1093. omp_firstprivatize_variable (ctx, GFC_TYPE_ARRAY_LBOUND (type, r));
  1094. omp_firstprivatize_variable (ctx, GFC_TYPE_ARRAY_UBOUND (type, r));
  1095. omp_firstprivatize_variable (ctx, GFC_TYPE_ARRAY_STRIDE (type, r));
  1096. }
  1097. omp_firstprivatize_variable (ctx, GFC_TYPE_ARRAY_SIZE (type));
  1098. omp_firstprivatize_variable (ctx, GFC_TYPE_ARRAY_OFFSET (type));
  1099. }
  1100. }
  1101. static inline tree
  1102. gfc_trans_add_clause (tree node, tree tail)
  1103. {
  1104. OMP_CLAUSE_CHAIN (node) = tail;
  1105. return node;
  1106. }
  1107. static tree
  1108. gfc_trans_omp_variable (gfc_symbol *sym, bool declare_simd)
  1109. {
  1110. if (declare_simd)
  1111. {
  1112. int cnt = 0;
  1113. gfc_symbol *proc_sym;
  1114. gfc_formal_arglist *f;
  1115. gcc_assert (sym->attr.dummy);
  1116. proc_sym = sym->ns->proc_name;
  1117. if (proc_sym->attr.entry_master)
  1118. ++cnt;
  1119. if (gfc_return_by_reference (proc_sym))
  1120. {
  1121. ++cnt;
  1122. if (proc_sym->ts.type == BT_CHARACTER)
  1123. ++cnt;
  1124. }
  1125. for (f = gfc_sym_get_dummy_args (proc_sym); f; f = f->next)
  1126. if (f->sym == sym)
  1127. break;
  1128. else if (f->sym)
  1129. ++cnt;
  1130. gcc_assert (f);
  1131. return build_int_cst (integer_type_node, cnt);
  1132. }
  1133. tree t = gfc_get_symbol_decl (sym);
  1134. tree parent_decl;
  1135. int parent_flag;
  1136. bool return_value;
  1137. bool alternate_entry;
  1138. bool entry_master;
  1139. return_value = sym->attr.function && sym->result == sym;
  1140. alternate_entry = sym->attr.function && sym->attr.entry
  1141. && sym->result == sym;
  1142. entry_master = sym->attr.result
  1143. && sym->ns->proc_name->attr.entry_master
  1144. && !gfc_return_by_reference (sym->ns->proc_name);
  1145. parent_decl = current_function_decl
  1146. ? DECL_CONTEXT (current_function_decl) : NULL_TREE;
  1147. if ((t == parent_decl && return_value)
  1148. || (sym->ns && sym->ns->proc_name
  1149. && sym->ns->proc_name->backend_decl == parent_decl
  1150. && (alternate_entry || entry_master)))
  1151. parent_flag = 1;
  1152. else
  1153. parent_flag = 0;
  1154. /* Special case for assigning the return value of a function.
  1155. Self recursive functions must have an explicit return value. */
  1156. if (return_value && (t == current_function_decl || parent_flag))
  1157. t = gfc_get_fake_result_decl (sym, parent_flag);
  1158. /* Similarly for alternate entry points. */
  1159. else if (alternate_entry
  1160. && (sym->ns->proc_name->backend_decl == current_function_decl
  1161. || parent_flag))
  1162. {
  1163. gfc_entry_list *el = NULL;
  1164. for (el = sym->ns->entries; el; el = el->next)
  1165. if (sym == el->sym)
  1166. {
  1167. t = gfc_get_fake_result_decl (sym, parent_flag);
  1168. break;
  1169. }
  1170. }
  1171. else if (entry_master
  1172. && (sym->ns->proc_name->backend_decl == current_function_decl
  1173. || parent_flag))
  1174. t = gfc_get_fake_result_decl (sym, parent_flag);
  1175. return t;
  1176. }
  1177. static tree
  1178. gfc_trans_omp_variable_list (enum omp_clause_code code,
  1179. gfc_omp_namelist *namelist, tree list,
  1180. bool declare_simd)
  1181. {
  1182. for (; namelist != NULL; namelist = namelist->next)
  1183. if (namelist->sym->attr.referenced || declare_simd)
  1184. {
  1185. tree t = gfc_trans_omp_variable (namelist->sym, declare_simd);
  1186. if (t != error_mark_node)
  1187. {
  1188. tree node = build_omp_clause (input_location, code);
  1189. OMP_CLAUSE_DECL (node) = t;
  1190. list = gfc_trans_add_clause (node, list);
  1191. }
  1192. }
  1193. return list;
  1194. }
  1195. struct omp_udr_find_orig_data
  1196. {
  1197. gfc_omp_udr *omp_udr;
  1198. bool omp_orig_seen;
  1199. };
  1200. static int
  1201. omp_udr_find_orig (gfc_expr **e, int *walk_subtrees ATTRIBUTE_UNUSED,
  1202. void *data)
  1203. {
  1204. struct omp_udr_find_orig_data *cd = (struct omp_udr_find_orig_data *) data;
  1205. if ((*e)->expr_type == EXPR_VARIABLE
  1206. && (*e)->symtree->n.sym == cd->omp_udr->omp_orig)
  1207. cd->omp_orig_seen = true;
  1208. return 0;
  1209. }
  1210. static void
  1211. gfc_trans_omp_array_reduction_or_udr (tree c, gfc_omp_namelist *n, locus where)
  1212. {
  1213. gfc_symbol *sym = n->sym;
  1214. gfc_symtree *root1 = NULL, *root2 = NULL, *root3 = NULL, *root4 = NULL;
  1215. gfc_symtree *symtree1, *symtree2, *symtree3, *symtree4 = NULL;
  1216. gfc_symbol init_val_sym, outer_sym, intrinsic_sym;
  1217. gfc_symbol omp_var_copy[4];
  1218. gfc_expr *e1, *e2, *e3, *e4;
  1219. gfc_ref *ref;
  1220. tree decl, backend_decl, stmt, type, outer_decl;
  1221. locus old_loc = gfc_current_locus;
  1222. const char *iname;
  1223. bool t;
  1224. gfc_omp_udr *udr = n->udr ? n->udr->udr : NULL;
  1225. decl = OMP_CLAUSE_DECL (c);
  1226. gfc_current_locus = where;
  1227. type = TREE_TYPE (decl);
  1228. outer_decl = create_tmp_var_raw (type);
  1229. if (TREE_CODE (decl) == PARM_DECL
  1230. && TREE_CODE (type) == REFERENCE_TYPE
  1231. && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (type))
  1232. && GFC_TYPE_ARRAY_AKIND (TREE_TYPE (type)) == GFC_ARRAY_ALLOCATABLE)
  1233. {
  1234. decl = build_fold_indirect_ref (decl);
  1235. type = TREE_TYPE (type);
  1236. }
  1237. /* Create a fake symbol for init value. */
  1238. memset (&init_val_sym, 0, sizeof (init_val_sym));
  1239. init_val_sym.ns = sym->ns;
  1240. init_val_sym.name = sym->name;
  1241. init_val_sym.ts = sym->ts;
  1242. init_val_sym.attr.referenced = 1;
  1243. init_val_sym.declared_at = where;
  1244. init_val_sym.attr.flavor = FL_VARIABLE;
  1245. if (OMP_CLAUSE_REDUCTION_CODE (c) != ERROR_MARK)
  1246. backend_decl = omp_reduction_init (c, gfc_sym_type (&init_val_sym));
  1247. else if (udr->initializer_ns)
  1248. backend_decl = NULL;
  1249. else
  1250. switch (sym->ts.type)
  1251. {
  1252. case BT_LOGICAL:
  1253. case BT_INTEGER:
  1254. case BT_REAL:
  1255. case BT_COMPLEX:
  1256. backend_decl = build_zero_cst (gfc_sym_type (&init_val_sym));
  1257. break;
  1258. default:
  1259. backend_decl = NULL_TREE;
  1260. break;
  1261. }
  1262. init_val_sym.backend_decl = backend_decl;
  1263. /* Create a fake symbol for the outer array reference. */
  1264. outer_sym = *sym;
  1265. if (sym->as)
  1266. outer_sym.as = gfc_copy_array_spec (sym->as);
  1267. outer_sym.attr.dummy = 0;
  1268. outer_sym.attr.result = 0;
  1269. outer_sym.attr.flavor = FL_VARIABLE;
  1270. outer_sym.backend_decl = outer_decl;
  1271. if (decl != OMP_CLAUSE_DECL (c))
  1272. outer_sym.backend_decl = build_fold_indirect_ref (outer_decl);
  1273. /* Create fake symtrees for it. */
  1274. symtree1 = gfc_new_symtree (&root1, sym->name);
  1275. symtree1->n.sym = sym;
  1276. gcc_assert (symtree1 == root1);
  1277. symtree2 = gfc_new_symtree (&root2, sym->name);
  1278. symtree2->n.sym = &init_val_sym;
  1279. gcc_assert (symtree2 == root2);
  1280. symtree3 = gfc_new_symtree (&root3, sym->name);
  1281. symtree3->n.sym = &outer_sym;
  1282. gcc_assert (symtree3 == root3);
  1283. memset (omp_var_copy, 0, sizeof omp_var_copy);
  1284. if (udr)
  1285. {
  1286. omp_var_copy[0] = *udr->omp_out;
  1287. omp_var_copy[1] = *udr->omp_in;
  1288. *udr->omp_out = outer_sym;
  1289. *udr->omp_in = *sym;
  1290. if (udr->initializer_ns)
  1291. {
  1292. omp_var_copy[2] = *udr->omp_priv;
  1293. omp_var_copy[3] = *udr->omp_orig;
  1294. *udr->omp_priv = *sym;
  1295. *udr->omp_orig = outer_sym;
  1296. }
  1297. }
  1298. /* Create expressions. */
  1299. e1 = gfc_get_expr ();
  1300. e1->expr_type = EXPR_VARIABLE;
  1301. e1->where = where;
  1302. e1->symtree = symtree1;
  1303. e1->ts = sym->ts;
  1304. if (sym->attr.dimension)
  1305. {
  1306. e1->ref = ref = gfc_get_ref ();
  1307. ref->type = REF_ARRAY;
  1308. ref->u.ar.where = where;
  1309. ref->u.ar.as = sym->as;
  1310. ref->u.ar.type = AR_FULL;
  1311. ref->u.ar.dimen = 0;
  1312. }
  1313. t = gfc_resolve_expr (e1);
  1314. gcc_assert (t);
  1315. e2 = NULL;
  1316. if (backend_decl != NULL_TREE)
  1317. {
  1318. e2 = gfc_get_expr ();
  1319. e2->expr_type = EXPR_VARIABLE;
  1320. e2->where = where;
  1321. e2->symtree = symtree2;
  1322. e2->ts = sym->ts;
  1323. t = gfc_resolve_expr (e2);
  1324. gcc_assert (t);
  1325. }
  1326. else if (udr->initializer_ns == NULL)
  1327. {
  1328. gcc_assert (sym->ts.type == BT_DERIVED);
  1329. e2 = gfc_default_initializer (&sym->ts);
  1330. gcc_assert (e2);
  1331. t = gfc_resolve_expr (e2);
  1332. gcc_assert (t);
  1333. }
  1334. else if (n->udr->initializer->op == EXEC_ASSIGN)
  1335. {
  1336. e2 = gfc_copy_expr (n->udr->initializer->expr2);
  1337. t = gfc_resolve_expr (e2);
  1338. gcc_assert (t);
  1339. }
  1340. if (udr && udr->initializer_ns)
  1341. {
  1342. struct omp_udr_find_orig_data cd;
  1343. cd.omp_udr = udr;
  1344. cd.omp_orig_seen = false;
  1345. gfc_code_walker (&n->udr->initializer,
  1346. gfc_dummy_code_callback, omp_udr_find_orig, &cd);
  1347. if (cd.omp_orig_seen)
  1348. OMP_CLAUSE_REDUCTION_OMP_ORIG_REF (c) = 1;
  1349. }
  1350. e3 = gfc_copy_expr (e1);
  1351. e3->symtree = symtree3;
  1352. t = gfc_resolve_expr (e3);
  1353. gcc_assert (t);
  1354. iname = NULL;
  1355. e4 = NULL;
  1356. switch (OMP_CLAUSE_REDUCTION_CODE (c))
  1357. {
  1358. case PLUS_EXPR:
  1359. case MINUS_EXPR:
  1360. e4 = gfc_add (e3, e1);
  1361. break;
  1362. case MULT_EXPR:
  1363. e4 = gfc_multiply (e3, e1);
  1364. break;
  1365. case TRUTH_ANDIF_EXPR:
  1366. e4 = gfc_and (e3, e1);
  1367. break;
  1368. case TRUTH_ORIF_EXPR:
  1369. e4 = gfc_or (e3, e1);
  1370. break;
  1371. case EQ_EXPR:
  1372. e4 = gfc_eqv (e3, e1);
  1373. break;
  1374. case NE_EXPR:
  1375. e4 = gfc_neqv (e3, e1);
  1376. break;
  1377. case MIN_EXPR:
  1378. iname = "min";
  1379. break;
  1380. case MAX_EXPR:
  1381. iname = "max";
  1382. break;
  1383. case BIT_AND_EXPR:
  1384. iname = "iand";
  1385. break;
  1386. case BIT_IOR_EXPR:
  1387. iname = "ior";
  1388. break;
  1389. case BIT_XOR_EXPR:
  1390. iname = "ieor";
  1391. break;
  1392. case ERROR_MARK:
  1393. if (n->udr->combiner->op == EXEC_ASSIGN)
  1394. {
  1395. gfc_free_expr (e3);
  1396. e3 = gfc_copy_expr (n->udr->combiner->expr1);
  1397. e4 = gfc_copy_expr (n->udr->combiner->expr2);
  1398. t = gfc_resolve_expr (e3);
  1399. gcc_assert (t);
  1400. t = gfc_resolve_expr (e4);
  1401. gcc_assert (t);
  1402. }
  1403. break;
  1404. default:
  1405. gcc_unreachable ();
  1406. }
  1407. if (iname != NULL)
  1408. {
  1409. memset (&intrinsic_sym, 0, sizeof (intrinsic_sym));
  1410. intrinsic_sym.ns = sym->ns;
  1411. intrinsic_sym.name = iname;
  1412. intrinsic_sym.ts = sym->ts;
  1413. intrinsic_sym.attr.referenced = 1;
  1414. intrinsic_sym.attr.intrinsic = 1;
  1415. intrinsic_sym.attr.function = 1;
  1416. intrinsic_sym.result = &intrinsic_sym;
  1417. intrinsic_sym.declared_at = where;
  1418. symtree4 = gfc_new_symtree (&root4, iname);
  1419. symtree4->n.sym = &intrinsic_sym;
  1420. gcc_assert (symtree4 == root4);
  1421. e4 = gfc_get_expr ();
  1422. e4->expr_type = EXPR_FUNCTION;
  1423. e4->where = where;
  1424. e4->symtree = symtree4;
  1425. e4->value.function.actual = gfc_get_actual_arglist ();
  1426. e4->value.function.actual->expr = e3;
  1427. e4->value.function.actual->next = gfc_get_actual_arglist ();
  1428. e4->value.function.actual->next->expr = e1;
  1429. }
  1430. if (OMP_CLAUSE_REDUCTION_CODE (c) != ERROR_MARK)
  1431. {
  1432. /* e1 and e3 have been stored as arguments of e4, avoid sharing. */
  1433. e1 = gfc_copy_expr (e1);
  1434. e3 = gfc_copy_expr (e3);
  1435. t = gfc_resolve_expr (e4);
  1436. gcc_assert (t);
  1437. }
  1438. /* Create the init statement list. */
  1439. pushlevel ();
  1440. if (e2)
  1441. stmt = gfc_trans_assignment (e1, e2, false, false);
  1442. else
  1443. stmt = gfc_trans_call (n->udr->initializer, false,
  1444. NULL_TREE, NULL_TREE, false);
  1445. if (TREE_CODE (stmt) != BIND_EXPR)
  1446. stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0));
  1447. else
  1448. poplevel (0, 0);
  1449. OMP_CLAUSE_REDUCTION_INIT (c) = stmt;
  1450. /* Create the merge statement list. */
  1451. pushlevel ();
  1452. if (e4)
  1453. stmt = gfc_trans_assignment (e3, e4, false, true);
  1454. else
  1455. stmt = gfc_trans_call (n->udr->combiner, false,
  1456. NULL_TREE, NULL_TREE, false);
  1457. if (TREE_CODE (stmt) != BIND_EXPR)
  1458. stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0));
  1459. else
  1460. poplevel (0, 0);
  1461. OMP_CLAUSE_REDUCTION_MERGE (c) = stmt;
  1462. /* And stick the placeholder VAR_DECL into the clause as well. */
  1463. OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) = outer_decl;
  1464. gfc_current_locus = old_loc;
  1465. gfc_free_expr (e1);
  1466. if (e2)
  1467. gfc_free_expr (e2);
  1468. gfc_free_expr (e3);
  1469. if (e4)
  1470. gfc_free_expr (e4);
  1471. free (symtree1);
  1472. free (symtree2);
  1473. free (symtree3);
  1474. free (symtree4);
  1475. if (outer_sym.as)
  1476. gfc_free_array_spec (outer_sym.as);
  1477. if (udr)
  1478. {
  1479. *udr->omp_out = omp_var_copy[0];
  1480. *udr->omp_in = omp_var_copy[1];
  1481. if (udr->initializer_ns)
  1482. {
  1483. *udr->omp_priv = omp_var_copy[2];
  1484. *udr->omp_orig = omp_var_copy[3];
  1485. }
  1486. }
  1487. }
  1488. static tree
  1489. gfc_trans_omp_reduction_list (gfc_omp_namelist *namelist, tree list,
  1490. locus where)
  1491. {
  1492. for (; namelist != NULL; namelist = namelist->next)
  1493. if (namelist->sym->attr.referenced)
  1494. {
  1495. tree t = gfc_trans_omp_variable (namelist->sym, false);
  1496. if (t != error_mark_node)
  1497. {
  1498. tree node = build_omp_clause (where.lb->location,
  1499. OMP_CLAUSE_REDUCTION);
  1500. OMP_CLAUSE_DECL (node) = t;
  1501. switch (namelist->u.reduction_op)
  1502. {
  1503. case OMP_REDUCTION_PLUS:
  1504. OMP_CLAUSE_REDUCTION_CODE (node) = PLUS_EXPR;
  1505. break;
  1506. case OMP_REDUCTION_MINUS:
  1507. OMP_CLAUSE_REDUCTION_CODE (node) = MINUS_EXPR;
  1508. break;
  1509. case OMP_REDUCTION_TIMES:
  1510. OMP_CLAUSE_REDUCTION_CODE (node) = MULT_EXPR;
  1511. break;
  1512. case OMP_REDUCTION_AND:
  1513. OMP_CLAUSE_REDUCTION_CODE (node) = TRUTH_ANDIF_EXPR;
  1514. break;
  1515. case OMP_REDUCTION_OR:
  1516. OMP_CLAUSE_REDUCTION_CODE (node) = TRUTH_ORIF_EXPR;
  1517. break;
  1518. case OMP_REDUCTION_EQV:
  1519. OMP_CLAUSE_REDUCTION_CODE (node) = EQ_EXPR;
  1520. break;
  1521. case OMP_REDUCTION_NEQV:
  1522. OMP_CLAUSE_REDUCTION_CODE (node) = NE_EXPR;
  1523. break;
  1524. case OMP_REDUCTION_MAX:
  1525. OMP_CLAUSE_REDUCTION_CODE (node) = MAX_EXPR;
  1526. break;
  1527. case OMP_REDUCTION_MIN:
  1528. OMP_CLAUSE_REDUCTION_CODE (node) = MIN_EXPR;
  1529. break;
  1530. case OMP_REDUCTION_IAND:
  1531. OMP_CLAUSE_REDUCTION_CODE (node) = BIT_AND_EXPR;
  1532. break;
  1533. case OMP_REDUCTION_IOR:
  1534. OMP_CLAUSE_REDUCTION_CODE (node) = BIT_IOR_EXPR;
  1535. break;
  1536. case OMP_REDUCTION_IEOR:
  1537. OMP_CLAUSE_REDUCTION_CODE (node) = BIT_XOR_EXPR;
  1538. break;
  1539. case OMP_REDUCTION_USER:
  1540. OMP_CLAUSE_REDUCTION_CODE (node) = ERROR_MARK;
  1541. break;
  1542. default:
  1543. gcc_unreachable ();
  1544. }
  1545. if (namelist->sym->attr.dimension
  1546. || namelist->u.reduction_op == OMP_REDUCTION_USER
  1547. || namelist->sym->attr.allocatable)
  1548. gfc_trans_omp_array_reduction_or_udr (node, namelist, where);
  1549. list = gfc_trans_add_clause (node, list);
  1550. }
  1551. }
  1552. return list;
  1553. }
  1554. static inline tree
  1555. gfc_convert_expr_to_tree (stmtblock_t *block, gfc_expr *expr)
  1556. {
  1557. gfc_se se;
  1558. tree result;
  1559. gfc_init_se (&se, NULL );
  1560. gfc_conv_expr (&se, expr);
  1561. gfc_add_block_to_block (block, &se.pre);
  1562. result = gfc_evaluate_now (se.expr, block);
  1563. gfc_add_block_to_block (block, &se.post);
  1564. return result;
  1565. }
  1566. static tree
  1567. gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses,
  1568. locus where, bool declare_simd = false)
  1569. {
  1570. tree omp_clauses = NULL_TREE, chunk_size, c;
  1571. int list;
  1572. enum omp_clause_code clause_code;
  1573. gfc_se se;
  1574. if (clauses == NULL)
  1575. return NULL_TREE;
  1576. for (list = 0; list < OMP_LIST_NUM; list++)
  1577. {
  1578. gfc_omp_namelist *n = clauses->lists[list];
  1579. if (n == NULL)
  1580. continue;
  1581. switch (list)
  1582. {
  1583. case OMP_LIST_REDUCTION:
  1584. omp_clauses = gfc_trans_omp_reduction_list (n, omp_clauses, where);
  1585. break;
  1586. case OMP_LIST_PRIVATE:
  1587. clause_code = OMP_CLAUSE_PRIVATE;
  1588. goto add_clause;
  1589. case OMP_LIST_SHARED:
  1590. clause_code = OMP_CLAUSE_SHARED;
  1591. goto add_clause;
  1592. case OMP_LIST_FIRSTPRIVATE:
  1593. clause_code = OMP_CLAUSE_FIRSTPRIVATE;
  1594. goto add_clause;
  1595. case OMP_LIST_LASTPRIVATE:
  1596. clause_code = OMP_CLAUSE_LASTPRIVATE;
  1597. goto add_clause;
  1598. case OMP_LIST_COPYIN:
  1599. clause_code = OMP_CLAUSE_COPYIN;
  1600. goto add_clause;
  1601. case OMP_LIST_COPYPRIVATE:
  1602. clause_code = OMP_CLAUSE_COPYPRIVATE;
  1603. goto add_clause;
  1604. case OMP_LIST_UNIFORM:
  1605. clause_code = OMP_CLAUSE_UNIFORM;
  1606. goto add_clause;
  1607. case OMP_LIST_USE_DEVICE:
  1608. clause_code = OMP_CLAUSE_USE_DEVICE;
  1609. goto add_clause;
  1610. case OMP_LIST_DEVICE_RESIDENT:
  1611. clause_code = OMP_CLAUSE_DEVICE_RESIDENT;
  1612. goto add_clause;
  1613. case OMP_LIST_CACHE:
  1614. clause_code = OMP_CLAUSE__CACHE_;
  1615. goto add_clause;
  1616. add_clause:
  1617. omp_clauses
  1618. = gfc_trans_omp_variable_list (clause_code, n, omp_clauses,
  1619. declare_simd);
  1620. break;
  1621. case OMP_LIST_ALIGNED:
  1622. for (; n != NULL; n = n->next)
  1623. if (n->sym->attr.referenced || declare_simd)
  1624. {
  1625. tree t = gfc_trans_omp_variable (n->sym, declare_simd);
  1626. if (t != error_mark_node)
  1627. {
  1628. tree node = build_omp_clause (input_location,
  1629. OMP_CLAUSE_ALIGNED);
  1630. OMP_CLAUSE_DECL (node) = t;
  1631. if (n->expr)
  1632. {
  1633. tree alignment_var;
  1634. if (block == NULL)
  1635. alignment_var = gfc_conv_constant_to_tree (n->expr);
  1636. else
  1637. {
  1638. gfc_init_se (&se, NULL);
  1639. gfc_conv_expr (&se, n->expr);
  1640. gfc_add_block_to_block (block, &se.pre);
  1641. alignment_var = gfc_evaluate_now (se.expr, block);
  1642. gfc_add_block_to_block (block, &se.post);
  1643. }
  1644. OMP_CLAUSE_ALIGNED_ALIGNMENT (node) = alignment_var;
  1645. }
  1646. omp_clauses = gfc_trans_add_clause (node, omp_clauses);
  1647. }
  1648. }
  1649. break;
  1650. case OMP_LIST_LINEAR:
  1651. {
  1652. gfc_expr *last_step_expr = NULL;
  1653. tree last_step = NULL_TREE;
  1654. for (; n != NULL; n = n->next)
  1655. {
  1656. if (n->expr)
  1657. {
  1658. last_step_expr = n->expr;
  1659. last_step = NULL_TREE;
  1660. }
  1661. if (n->sym->attr.referenced || declare_simd)
  1662. {
  1663. tree t = gfc_trans_omp_variable (n->sym, declare_simd);
  1664. if (t != error_mark_node)
  1665. {
  1666. tree node = build_omp_clause (input_location,
  1667. OMP_CLAUSE_LINEAR);
  1668. OMP_CLAUSE_DECL (node) = t;
  1669. if (last_step_expr && last_step == NULL_TREE)
  1670. {
  1671. if (block == NULL)
  1672. last_step
  1673. = gfc_conv_constant_to_tree (last_step_expr);
  1674. else
  1675. {
  1676. gfc_init_se (&se, NULL);
  1677. gfc_conv_expr (&se, last_step_expr);
  1678. gfc_add_block_to_block (block, &se.pre);
  1679. last_step = gfc_evaluate_now (se.expr, block);
  1680. gfc_add_block_to_block (block, &se.post);
  1681. }
  1682. }
  1683. OMP_CLAUSE_LINEAR_STEP (node)
  1684. = fold_convert (gfc_typenode_for_spec (&n->sym->ts),
  1685. last_step);
  1686. if (n->sym->attr.dimension || n->sym->attr.allocatable)
  1687. OMP_CLAUSE_LINEAR_ARRAY (node) = 1;
  1688. omp_clauses = gfc_trans_add_clause (node, omp_clauses);
  1689. }
  1690. }
  1691. }
  1692. }
  1693. break;
  1694. case OMP_LIST_DEPEND:
  1695. for (; n != NULL; n = n->next)
  1696. {
  1697. if (!n->sym->attr.referenced)
  1698. continue;
  1699. tree node = build_omp_clause (input_location, OMP_CLAUSE_DEPEND);
  1700. if (n->expr == NULL || n->expr->ref->u.ar.type == AR_FULL)
  1701. {
  1702. tree decl = gfc_get_symbol_decl (n->sym);
  1703. if (gfc_omp_privatize_by_reference (decl))
  1704. decl = build_fold_indirect_ref (decl);
  1705. if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl)))
  1706. {
  1707. decl = gfc_conv_descriptor_data_get (decl);
  1708. decl = fold_convert (build_pointer_type (char_type_node),
  1709. decl);
  1710. decl = build_fold_indirect_ref (decl);
  1711. }
  1712. else if (DECL_P (decl))
  1713. TREE_ADDRESSABLE (decl) = 1;
  1714. OMP_CLAUSE_DECL (node) = decl;
  1715. }
  1716. else
  1717. {
  1718. tree ptr;
  1719. gfc_init_se (&se, NULL);
  1720. if (n->expr->ref->u.ar.type == AR_ELEMENT)
  1721. {
  1722. gfc_conv_expr_reference (&se, n->expr);
  1723. ptr = se.expr;
  1724. }
  1725. else
  1726. {
  1727. gfc_conv_expr_descriptor (&se, n->expr);
  1728. ptr = gfc_conv_array_data (se.expr);
  1729. }
  1730. gfc_add_block_to_block (block, &se.pre);
  1731. gfc_add_block_to_block (block, &se.post);
  1732. ptr = fold_convert (build_pointer_type (char_type_node),
  1733. ptr);
  1734. OMP_CLAUSE_DECL (node) = build_fold_indirect_ref (ptr);
  1735. }
  1736. switch (n->u.depend_op)
  1737. {
  1738. case OMP_DEPEND_IN:
  1739. OMP_CLAUSE_DEPEND_KIND (node) = OMP_CLAUSE_DEPEND_IN;
  1740. break;
  1741. case OMP_DEPEND_OUT:
  1742. OMP_CLAUSE_DEPEND_KIND (node) = OMP_CLAUSE_DEPEND_OUT;
  1743. break;
  1744. case OMP_DEPEND_INOUT:
  1745. OMP_CLAUSE_DEPEND_KIND (node) = OMP_CLAUSE_DEPEND_INOUT;
  1746. break;
  1747. default:
  1748. gcc_unreachable ();
  1749. }
  1750. omp_clauses = gfc_trans_add_clause (node, omp_clauses);
  1751. }
  1752. break;
  1753. case OMP_LIST_MAP:
  1754. for (; n != NULL; n = n->next)
  1755. {
  1756. if (!n->sym->attr.referenced)
  1757. continue;
  1758. tree node = build_omp_clause (input_location, OMP_CLAUSE_MAP);
  1759. tree node2 = NULL_TREE;
  1760. tree node3 = NULL_TREE;
  1761. tree node4 = NULL_TREE;
  1762. tree decl = gfc_get_symbol_decl (n->sym);
  1763. if (DECL_P (decl))
  1764. TREE_ADDRESSABLE (decl) = 1;
  1765. if (n->expr == NULL || n->expr->ref->u.ar.type == AR_FULL)
  1766. {
  1767. if (POINTER_TYPE_P (TREE_TYPE (decl))
  1768. && (gfc_omp_privatize_by_reference (decl)
  1769. || GFC_DECL_GET_SCALAR_POINTER (decl)
  1770. || GFC_DECL_GET_SCALAR_ALLOCATABLE (decl)
  1771. || GFC_DECL_CRAY_POINTEE (decl)
  1772. || GFC_DESCRIPTOR_TYPE_P
  1773. (TREE_TYPE (TREE_TYPE (decl)))))
  1774. {
  1775. tree orig_decl = decl;
  1776. node4 = build_omp_clause (input_location,
  1777. OMP_CLAUSE_MAP);
  1778. OMP_CLAUSE_SET_MAP_KIND (node4, GOMP_MAP_POINTER);
  1779. OMP_CLAUSE_DECL (node4) = decl;
  1780. OMP_CLAUSE_SIZE (node4) = size_int (0);
  1781. decl = build_fold_indirect_ref (decl);
  1782. if (TREE_CODE (TREE_TYPE (orig_decl)) == REFERENCE_TYPE
  1783. && (GFC_DECL_GET_SCALAR_POINTER (orig_decl)
  1784. || GFC_DECL_GET_SCALAR_ALLOCATABLE (orig_decl)))
  1785. {
  1786. node3 = build_omp_clause (input_location,
  1787. OMP_CLAUSE_MAP);
  1788. OMP_CLAUSE_SET_MAP_KIND (node3, GOMP_MAP_POINTER);
  1789. OMP_CLAUSE_DECL (node3) = decl;
  1790. OMP_CLAUSE_SIZE (node3) = size_int (0);
  1791. decl = build_fold_indirect_ref (decl);
  1792. }
  1793. }
  1794. if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl)))
  1795. {
  1796. tree type = TREE_TYPE (decl);
  1797. tree ptr = gfc_conv_descriptor_data_get (decl);
  1798. ptr = fold_convert (build_pointer_type (char_type_node),
  1799. ptr);
  1800. ptr = build_fold_indirect_ref (ptr);
  1801. OMP_CLAUSE_DECL (node) = ptr;
  1802. node2 = build_omp_clause (input_location,
  1803. OMP_CLAUSE_MAP);
  1804. OMP_CLAUSE_SET_MAP_KIND (node2, GOMP_MAP_TO_PSET);
  1805. OMP_CLAUSE_DECL (node2) = decl;
  1806. OMP_CLAUSE_SIZE (node2) = TYPE_SIZE_UNIT (type);
  1807. node3 = build_omp_clause (input_location,
  1808. OMP_CLAUSE_MAP);
  1809. OMP_CLAUSE_SET_MAP_KIND (node3, GOMP_MAP_POINTER);
  1810. OMP_CLAUSE_DECL (node3)
  1811. = gfc_conv_descriptor_data_get (decl);
  1812. OMP_CLAUSE_SIZE (node3) = size_int (0);
  1813. /* We have to check for n->sym->attr.dimension because
  1814. of scalar coarrays. */
  1815. if (n->sym->attr.pointer && n->sym->attr.dimension)
  1816. {
  1817. stmtblock_t cond_block;
  1818. tree size
  1819. = gfc_create_var (gfc_array_index_type, NULL);
  1820. tree tem, then_b, else_b, zero, cond;
  1821. gfc_init_block (&cond_block);
  1822. tem
  1823. = gfc_full_array_size (&cond_block, decl,
  1824. GFC_TYPE_ARRAY_RANK (type));
  1825. gfc_add_modify (&cond_block, size, tem);
  1826. then_b = gfc_finish_block (&cond_block);
  1827. gfc_init_block (&cond_block);
  1828. zero = build_int_cst (gfc_array_index_type, 0);
  1829. gfc_add_modify (&cond_block, size, zero);
  1830. else_b = gfc_finish_block (&cond_block);
  1831. tem = gfc_conv_descriptor_data_get (decl);
  1832. tem = fold_convert (pvoid_type_node, tem);
  1833. cond = fold_build2_loc (input_location, NE_EXPR,
  1834. boolean_type_node,
  1835. tem, null_pointer_node);
  1836. gfc_add_expr_to_block (block,
  1837. build3_loc (input_location,
  1838. COND_EXPR,
  1839. void_type_node,
  1840. cond, then_b,
  1841. else_b));
  1842. OMP_CLAUSE_SIZE (node) = size;
  1843. }
  1844. else if (n->sym->attr.dimension)
  1845. OMP_CLAUSE_SIZE (node)
  1846. = gfc_full_array_size (block, decl,
  1847. GFC_TYPE_ARRAY_RANK (type));
  1848. if (n->sym->attr.dimension)
  1849. {
  1850. tree elemsz
  1851. = TYPE_SIZE_UNIT (gfc_get_element_type (type));
  1852. elemsz = fold_convert (gfc_array_index_type, elemsz);
  1853. OMP_CLAUSE_SIZE (node)
  1854. = fold_build2 (MULT_EXPR, gfc_array_index_type,
  1855. OMP_CLAUSE_SIZE (node), elemsz);
  1856. }
  1857. }
  1858. else
  1859. OMP_CLAUSE_DECL (node) = decl;
  1860. }
  1861. else
  1862. {
  1863. tree ptr, ptr2;
  1864. gfc_init_se (&se, NULL);
  1865. if (n->expr->ref->u.ar.type == AR_ELEMENT)
  1866. {
  1867. gfc_conv_expr_reference (&se, n->expr);
  1868. gfc_add_block_to_block (block, &se.pre);
  1869. ptr = se.expr;
  1870. OMP_CLAUSE_SIZE (node)
  1871. = TYPE_SIZE_UNIT (TREE_TYPE (ptr));
  1872. }
  1873. else
  1874. {
  1875. gfc_conv_expr_descriptor (&se, n->expr);
  1876. ptr = gfc_conv_array_data (se.expr);
  1877. tree type = TREE_TYPE (se.expr);
  1878. gfc_add_block_to_block (block, &se.pre);
  1879. OMP_CLAUSE_SIZE (node)
  1880. = gfc_full_array_size (block, se.expr,
  1881. GFC_TYPE_ARRAY_RANK (type));
  1882. tree elemsz
  1883. = TYPE_SIZE_UNIT (gfc_get_element_type (type));
  1884. elemsz = fold_convert (gfc_array_index_type, elemsz);
  1885. OMP_CLAUSE_SIZE (node)
  1886. = fold_build2 (MULT_EXPR, gfc_array_index_type,
  1887. OMP_CLAUSE_SIZE (node), elemsz);
  1888. }
  1889. gfc_add_block_to_block (block, &se.post);
  1890. ptr = fold_convert (build_pointer_type (char_type_node),
  1891. ptr);
  1892. OMP_CLAUSE_DECL (node) = build_fold_indirect_ref (ptr);
  1893. if (POINTER_TYPE_P (TREE_TYPE (decl))
  1894. && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (TREE_TYPE (decl))))
  1895. {
  1896. node4 = build_omp_clause (input_location,
  1897. OMP_CLAUSE_MAP);
  1898. OMP_CLAUSE_SET_MAP_KIND (node4, GOMP_MAP_POINTER);
  1899. OMP_CLAUSE_DECL (node4) = decl;
  1900. OMP_CLAUSE_SIZE (node4) = size_int (0);
  1901. decl = build_fold_indirect_ref (decl);
  1902. }
  1903. ptr = fold_convert (sizetype, ptr);
  1904. if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl)))
  1905. {
  1906. tree type = TREE_TYPE (decl);
  1907. ptr2 = gfc_conv_descriptor_data_get (decl);
  1908. node2 = build_omp_clause (input_location,
  1909. OMP_CLAUSE_MAP);
  1910. OMP_CLAUSE_SET_MAP_KIND (node2, GOMP_MAP_TO_PSET);
  1911. OMP_CLAUSE_DECL (node2) = decl;
  1912. OMP_CLAUSE_SIZE (node2) = TYPE_SIZE_UNIT (type);
  1913. node3 = build_omp_clause (input_location,
  1914. OMP_CLAUSE_MAP);
  1915. OMP_CLAUSE_SET_MAP_KIND (node3, GOMP_MAP_POINTER);
  1916. OMP_CLAUSE_DECL (node3)
  1917. = gfc_conv_descriptor_data_get (decl);
  1918. }
  1919. else
  1920. {
  1921. if (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
  1922. ptr2 = build_fold_addr_expr (decl);
  1923. else
  1924. {
  1925. gcc_assert (POINTER_TYPE_P (TREE_TYPE (decl)));
  1926. ptr2 = decl;
  1927. }
  1928. node3 = build_omp_clause (input_location,
  1929. OMP_CLAUSE_MAP);
  1930. OMP_CLAUSE_SET_MAP_KIND (node3, GOMP_MAP_POINTER);
  1931. OMP_CLAUSE_DECL (node3) = decl;
  1932. }
  1933. ptr2 = fold_convert (sizetype, ptr2);
  1934. OMP_CLAUSE_SIZE (node3)
  1935. = fold_build2 (MINUS_EXPR, sizetype, ptr, ptr2);
  1936. }
  1937. switch (n->u.map_op)
  1938. {
  1939. case OMP_MAP_ALLOC:
  1940. OMP_CLAUSE_SET_MAP_KIND (node, GOMP_MAP_ALLOC);
  1941. break;
  1942. case OMP_MAP_TO:
  1943. OMP_CLAUSE_SET_MAP_KIND (node, GOMP_MAP_TO);
  1944. break;
  1945. case OMP_MAP_FROM:
  1946. OMP_CLAUSE_SET_MAP_KIND (node, GOMP_MAP_FROM);
  1947. break;
  1948. case OMP_MAP_TOFROM:
  1949. OMP_CLAUSE_SET_MAP_KIND (node, GOMP_MAP_TOFROM);
  1950. break;
  1951. case OMP_MAP_FORCE_ALLOC:
  1952. OMP_CLAUSE_SET_MAP_KIND (node, GOMP_MAP_FORCE_ALLOC);
  1953. break;
  1954. case OMP_MAP_FORCE_DEALLOC:
  1955. OMP_CLAUSE_SET_MAP_KIND (node, GOMP_MAP_FORCE_DEALLOC);
  1956. break;
  1957. case OMP_MAP_FORCE_TO:
  1958. OMP_CLAUSE_SET_MAP_KIND (node, GOMP_MAP_FORCE_TO);
  1959. break;
  1960. case OMP_MAP_FORCE_FROM:
  1961. OMP_CLAUSE_SET_MAP_KIND (node, GOMP_MAP_FORCE_FROM);
  1962. break;
  1963. case OMP_MAP_FORCE_TOFROM:
  1964. OMP_CLAUSE_SET_MAP_KIND (node, GOMP_MAP_FORCE_TOFROM);
  1965. break;
  1966. case OMP_MAP_FORCE_PRESENT:
  1967. OMP_CLAUSE_SET_MAP_KIND (node, GOMP_MAP_FORCE_PRESENT);
  1968. break;
  1969. case OMP_MAP_FORCE_DEVICEPTR:
  1970. OMP_CLAUSE_SET_MAP_KIND (node, GOMP_MAP_FORCE_DEVICEPTR);
  1971. break;
  1972. default:
  1973. gcc_unreachable ();
  1974. }
  1975. omp_clauses = gfc_trans_add_clause (node, omp_clauses);
  1976. if (node2)
  1977. omp_clauses = gfc_trans_add_clause (node2, omp_clauses);
  1978. if (node3)
  1979. omp_clauses = gfc_trans_add_clause (node3, omp_clauses);
  1980. if (node4)
  1981. omp_clauses = gfc_trans_add_clause (node4, omp_clauses);
  1982. }
  1983. break;
  1984. case OMP_LIST_TO:
  1985. case OMP_LIST_FROM:
  1986. for (; n != NULL; n = n->next)
  1987. {
  1988. if (!n->sym->attr.referenced)
  1989. continue;
  1990. tree node = build_omp_clause (input_location,
  1991. list == OMP_LIST_TO
  1992. ? OMP_CLAUSE_TO : OMP_CLAUSE_FROM);
  1993. if (n->expr == NULL || n->expr->ref->u.ar.type == AR_FULL)
  1994. {
  1995. tree decl = gfc_get_symbol_decl (n->sym);
  1996. if (gfc_omp_privatize_by_reference (decl))
  1997. decl = build_fold_indirect_ref (decl);
  1998. if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl)))
  1999. {
  2000. tree type = TREE_TYPE (decl);
  2001. tree ptr = gfc_conv_descriptor_data_get (decl);
  2002. ptr = fold_convert (build_pointer_type (char_type_node),
  2003. ptr);
  2004. ptr = build_fold_indirect_ref (ptr);
  2005. OMP_CLAUSE_DECL (node) = ptr;
  2006. OMP_CLAUSE_SIZE (node)
  2007. = gfc_full_array_size (block, decl,
  2008. GFC_TYPE_ARRAY_RANK (type));
  2009. tree elemsz
  2010. = TYPE_SIZE_UNIT (gfc_get_element_type (type));
  2011. elemsz = fold_convert (gfc_array_index_type, elemsz);
  2012. OMP_CLAUSE_SIZE (node)
  2013. = fold_build2 (MULT_EXPR, gfc_array_index_type,
  2014. OMP_CLAUSE_SIZE (node), elemsz);
  2015. }
  2016. else
  2017. OMP_CLAUSE_DECL (node) = decl;
  2018. }
  2019. else
  2020. {
  2021. tree ptr;
  2022. gfc_init_se (&se, NULL);
  2023. if (n->expr->ref->u.ar.type == AR_ELEMENT)
  2024. {
  2025. gfc_conv_expr_reference (&se, n->expr);
  2026. ptr = se.expr;
  2027. gfc_add_block_to_block (block, &se.pre);
  2028. OMP_CLAUSE_SIZE (node)
  2029. = TYPE_SIZE_UNIT (TREE_TYPE (ptr));
  2030. }
  2031. else
  2032. {
  2033. gfc_conv_expr_descriptor (&se, n->expr);
  2034. ptr = gfc_conv_array_data (se.expr);
  2035. tree type = TREE_TYPE (se.expr);
  2036. gfc_add_block_to_block (block, &se.pre);
  2037. OMP_CLAUSE_SIZE (node)
  2038. = gfc_full_array_size (block, se.expr,
  2039. GFC_TYPE_ARRAY_RANK (type));
  2040. tree elemsz
  2041. = TYPE_SIZE_UNIT (gfc_get_element_type (type));
  2042. elemsz = fold_convert (gfc_array_index_type, elemsz);
  2043. OMP_CLAUSE_SIZE (node)
  2044. = fold_build2 (MULT_EXPR, gfc_array_index_type,
  2045. OMP_CLAUSE_SIZE (node), elemsz);
  2046. }
  2047. gfc_add_block_to_block (block, &se.post);
  2048. ptr = fold_convert (build_pointer_type (char_type_node),
  2049. ptr);
  2050. OMP_CLAUSE_DECL (node) = build_fold_indirect_ref (ptr);
  2051. }
  2052. omp_clauses = gfc_trans_add_clause (node, omp_clauses);
  2053. }
  2054. break;
  2055. default:
  2056. break;
  2057. }
  2058. }
  2059. if (clauses->if_expr)
  2060. {
  2061. tree if_var;
  2062. gfc_init_se (&se, NULL);
  2063. gfc_conv_expr (&se, clauses->if_expr);
  2064. gfc_add_block_to_block (block, &se.pre);
  2065. if_var = gfc_evaluate_now (se.expr, block);
  2066. gfc_add_block_to_block (block, &se.post);
  2067. c = build_omp_clause (where.lb->location, OMP_CLAUSE_IF);
  2068. OMP_CLAUSE_IF_EXPR (c) = if_var;
  2069. omp_clauses = gfc_trans_add_clause (c, omp_clauses);
  2070. }
  2071. if (clauses->final_expr)
  2072. {
  2073. tree final_var;
  2074. gfc_init_se (&se, NULL);
  2075. gfc_conv_expr (&se, clauses->final_expr);
  2076. gfc_add_block_to_block (block, &se.pre);
  2077. final_var = gfc_evaluate_now (se.expr, block);
  2078. gfc_add_block_to_block (block, &se.post);
  2079. c = build_omp_clause (where.lb->location, OMP_CLAUSE_FINAL);
  2080. OMP_CLAUSE_FINAL_EXPR (c) = final_var;
  2081. omp_clauses = gfc_trans_add_clause (c, omp_clauses);
  2082. }
  2083. if (clauses->num_threads)
  2084. {
  2085. tree num_threads;
  2086. gfc_init_se (&se, NULL);
  2087. gfc_conv_expr (&se, clauses->num_threads);
  2088. gfc_add_block_to_block (block, &se.pre);
  2089. num_threads = gfc_evaluate_now (se.expr, block);
  2090. gfc_add_block_to_block (block, &se.post);
  2091. c = build_omp_clause (where.lb->location, OMP_CLAUSE_NUM_THREADS);
  2092. OMP_CLAUSE_NUM_THREADS_EXPR (c) = num_threads;
  2093. omp_clauses = gfc_trans_add_clause (c, omp_clauses);
  2094. }
  2095. chunk_size = NULL_TREE;
  2096. if (clauses->chunk_size)
  2097. {
  2098. gfc_init_se (&se, NULL);
  2099. gfc_conv_expr (&se, clauses->chunk_size);
  2100. gfc_add_block_to_block (block, &se.pre);
  2101. chunk_size = gfc_evaluate_now (se.expr, block);
  2102. gfc_add_block_to_block (block, &se.post);
  2103. }
  2104. if (clauses->sched_kind != OMP_SCHED_NONE)
  2105. {
  2106. c = build_omp_clause (where.lb->location, OMP_CLAUSE_SCHEDULE);
  2107. OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c) = chunk_size;
  2108. switch (clauses->sched_kind)
  2109. {
  2110. case OMP_SCHED_STATIC:
  2111. OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_STATIC;
  2112. break;
  2113. case OMP_SCHED_DYNAMIC:
  2114. OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_DYNAMIC;
  2115. break;
  2116. case OMP_SCHED_GUIDED:
  2117. OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_GUIDED;
  2118. break;
  2119. case OMP_SCHED_RUNTIME:
  2120. OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_RUNTIME;
  2121. break;
  2122. case OMP_SCHED_AUTO:
  2123. OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_AUTO;
  2124. break;
  2125. default:
  2126. gcc_unreachable ();
  2127. }
  2128. omp_clauses = gfc_trans_add_clause (c, omp_clauses);
  2129. }
  2130. if (clauses->default_sharing != OMP_DEFAULT_UNKNOWN)
  2131. {
  2132. c = build_omp_clause (where.lb->location, OMP_CLAUSE_DEFAULT);
  2133. switch (clauses->default_sharing)
  2134. {
  2135. case OMP_DEFAULT_NONE:
  2136. OMP_CLAUSE_DEFAULT_KIND (c) = OMP_CLAUSE_DEFAULT_NONE;
  2137. break;
  2138. case OMP_DEFAULT_SHARED:
  2139. OMP_CLAUSE_DEFAULT_KIND (c) = OMP_CLAUSE_DEFAULT_SHARED;
  2140. break;
  2141. case OMP_DEFAULT_PRIVATE:
  2142. OMP_CLAUSE_DEFAULT_KIND (c) = OMP_CLAUSE_DEFAULT_PRIVATE;
  2143. break;
  2144. case OMP_DEFAULT_FIRSTPRIVATE:
  2145. OMP_CLAUSE_DEFAULT_KIND (c) = OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;
  2146. break;
  2147. default:
  2148. gcc_unreachable ();
  2149. }
  2150. omp_clauses = gfc_trans_add_clause (c, omp_clauses);
  2151. }
  2152. if (clauses->nowait)
  2153. {
  2154. c = build_omp_clause (where.lb->location, OMP_CLAUSE_NOWAIT);
  2155. omp_clauses = gfc_trans_add_clause (c, omp_clauses);
  2156. }
  2157. if (clauses->ordered)
  2158. {
  2159. c = build_omp_clause (where.lb->location, OMP_CLAUSE_ORDERED);
  2160. omp_clauses = gfc_trans_add_clause (c, omp_clauses);
  2161. }
  2162. if (clauses->untied)
  2163. {
  2164. c = build_omp_clause (where.lb->location, OMP_CLAUSE_UNTIED);
  2165. omp_clauses = gfc_trans_add_clause (c, omp_clauses);
  2166. }
  2167. if (clauses->mergeable)
  2168. {
  2169. c = build_omp_clause (where.lb->location, OMP_CLAUSE_MERGEABLE);
  2170. omp_clauses = gfc_trans_add_clause (c, omp_clauses);
  2171. }
  2172. if (clauses->collapse)
  2173. {
  2174. c = build_omp_clause (where.lb->location, OMP_CLAUSE_COLLAPSE);
  2175. OMP_CLAUSE_COLLAPSE_EXPR (c)
  2176. = build_int_cst (integer_type_node, clauses->collapse);
  2177. omp_clauses = gfc_trans_add_clause (c, omp_clauses);
  2178. }
  2179. if (clauses->inbranch)
  2180. {
  2181. c = build_omp_clause (where.lb->location, OMP_CLAUSE_INBRANCH);
  2182. omp_clauses = gfc_trans_add_clause (c, omp_clauses);
  2183. }
  2184. if (clauses->notinbranch)
  2185. {
  2186. c = build_omp_clause (where.lb->location, OMP_CLAUSE_NOTINBRANCH);
  2187. omp_clauses = gfc_trans_add_clause (c, omp_clauses);
  2188. }
  2189. switch (clauses->cancel)
  2190. {
  2191. case OMP_CANCEL_UNKNOWN:
  2192. break;
  2193. case OMP_CANCEL_PARALLEL:
  2194. c = build_omp_clause (where.lb->location, OMP_CLAUSE_PARALLEL);
  2195. omp_clauses = gfc_trans_add_clause (c, omp_clauses);
  2196. break;
  2197. case OMP_CANCEL_SECTIONS:
  2198. c = build_omp_clause (where.lb->location, OMP_CLAUSE_SECTIONS);
  2199. omp_clauses = gfc_trans_add_clause (c, omp_clauses);
  2200. break;
  2201. case OMP_CANCEL_DO:
  2202. c = build_omp_clause (where.lb->location, OMP_CLAUSE_FOR);
  2203. omp_clauses = gfc_trans_add_clause (c, omp_clauses);
  2204. break;
  2205. case OMP_CANCEL_TASKGROUP:
  2206. c = build_omp_clause (where.lb->location, OMP_CLAUSE_TASKGROUP);
  2207. omp_clauses = gfc_trans_add_clause (c, omp_clauses);
  2208. break;
  2209. }
  2210. if (clauses->proc_bind != OMP_PROC_BIND_UNKNOWN)
  2211. {
  2212. c = build_omp_clause (where.lb->location, OMP_CLAUSE_PROC_BIND);
  2213. switch (clauses->proc_bind)
  2214. {
  2215. case OMP_PROC_BIND_MASTER:
  2216. OMP_CLAUSE_PROC_BIND_KIND (c) = OMP_CLAUSE_PROC_BIND_MASTER;
  2217. break;
  2218. case OMP_PROC_BIND_SPREAD:
  2219. OMP_CLAUSE_PROC_BIND_KIND (c) = OMP_CLAUSE_PROC_BIND_SPREAD;
  2220. break;
  2221. case OMP_PROC_BIND_CLOSE:
  2222. OMP_CLAUSE_PROC_BIND_KIND (c) = OMP_CLAUSE_PROC_BIND_CLOSE;
  2223. break;
  2224. default:
  2225. gcc_unreachable ();
  2226. }
  2227. omp_clauses = gfc_trans_add_clause (c, omp_clauses);
  2228. }
  2229. if (clauses->safelen_expr)
  2230. {
  2231. tree safelen_var;
  2232. gfc_init_se (&se, NULL);
  2233. gfc_conv_expr (&se, clauses->safelen_expr);
  2234. gfc_add_block_to_block (block, &se.pre);
  2235. safelen_var = gfc_evaluate_now (se.expr, block);
  2236. gfc_add_block_to_block (block, &se.post);
  2237. c = build_omp_clause (where.lb->location, OMP_CLAUSE_SAFELEN);
  2238. OMP_CLAUSE_SAFELEN_EXPR (c) = safelen_var;
  2239. omp_clauses = gfc_trans_add_clause (c, omp_clauses);
  2240. }
  2241. if (clauses->simdlen_expr)
  2242. {
  2243. c = build_omp_clause (where.lb->location, OMP_CLAUSE_SIMDLEN);
  2244. OMP_CLAUSE_SIMDLEN_EXPR (c)
  2245. = gfc_conv_constant_to_tree (clauses->simdlen_expr);
  2246. omp_clauses = gfc_trans_add_clause (c, omp_clauses);
  2247. }
  2248. if (clauses->num_teams)
  2249. {
  2250. tree num_teams;
  2251. gfc_init_se (&se, NULL);
  2252. gfc_conv_expr (&se, clauses->num_teams);
  2253. gfc_add_block_to_block (block, &se.pre);
  2254. num_teams = gfc_evaluate_now (se.expr, block);
  2255. gfc_add_block_to_block (block, &se.post);
  2256. c = build_omp_clause (where.lb->location, OMP_CLAUSE_NUM_TEAMS);
  2257. OMP_CLAUSE_NUM_TEAMS_EXPR (c) = num_teams;
  2258. omp_clauses = gfc_trans_add_clause (c, omp_clauses);
  2259. }
  2260. if (clauses->device)
  2261. {
  2262. tree device;
  2263. gfc_init_se (&se, NULL);
  2264. gfc_conv_expr (&se, clauses->device);
  2265. gfc_add_block_to_block (block, &se.pre);
  2266. device = gfc_evaluate_now (se.expr, block);
  2267. gfc_add_block_to_block (block, &se.post);
  2268. c = build_omp_clause (where.lb->location, OMP_CLAUSE_DEVICE);
  2269. OMP_CLAUSE_DEVICE_ID (c) = device;
  2270. omp_clauses = gfc_trans_add_clause (c, omp_clauses);
  2271. }
  2272. if (clauses->thread_limit)
  2273. {
  2274. tree thread_limit;
  2275. gfc_init_se (&se, NULL);
  2276. gfc_conv_expr (&se, clauses->thread_limit);
  2277. gfc_add_block_to_block (block, &se.pre);
  2278. thread_limit = gfc_evaluate_now (se.expr, block);
  2279. gfc_add_block_to_block (block, &se.post);
  2280. c = build_omp_clause (where.lb->location, OMP_CLAUSE_THREAD_LIMIT);
  2281. OMP_CLAUSE_THREAD_LIMIT_EXPR (c) = thread_limit;
  2282. omp_clauses = gfc_trans_add_clause (c, omp_clauses);
  2283. }
  2284. chunk_size = NULL_TREE;
  2285. if (clauses->dist_chunk_size)
  2286. {
  2287. gfc_init_se (&se, NULL);
  2288. gfc_conv_expr (&se, clauses->dist_chunk_size);
  2289. gfc_add_block_to_block (block, &se.pre);
  2290. chunk_size = gfc_evaluate_now (se.expr, block);
  2291. gfc_add_block_to_block (block, &se.post);
  2292. }
  2293. if (clauses->dist_sched_kind != OMP_SCHED_NONE)
  2294. {
  2295. c = build_omp_clause (where.lb->location, OMP_CLAUSE_DIST_SCHEDULE);
  2296. OMP_CLAUSE_DIST_SCHEDULE_CHUNK_EXPR (c) = chunk_size;
  2297. omp_clauses = gfc_trans_add_clause (c, omp_clauses);
  2298. }
  2299. if (clauses->async)
  2300. {
  2301. c = build_omp_clause (where.lb->location, OMP_CLAUSE_ASYNC);
  2302. if (clauses->async_expr)
  2303. OMP_CLAUSE_ASYNC_EXPR (c)
  2304. = gfc_convert_expr_to_tree (block, clauses->async_expr);
  2305. else
  2306. OMP_CLAUSE_ASYNC_EXPR (c) = NULL;
  2307. omp_clauses = gfc_trans_add_clause (c, omp_clauses);
  2308. }
  2309. if (clauses->seq)
  2310. {
  2311. c = build_omp_clause (where.lb->location, OMP_CLAUSE_ORDERED);
  2312. omp_clauses = gfc_trans_add_clause (c, omp_clauses);
  2313. }
  2314. if (clauses->independent)
  2315. {
  2316. c = build_omp_clause (where.lb->location, OMP_CLAUSE_INDEPENDENT);
  2317. omp_clauses = gfc_trans_add_clause (c, omp_clauses);
  2318. }
  2319. if (clauses->wait_list)
  2320. {
  2321. gfc_expr_list *el;
  2322. for (el = clauses->wait_list; el; el = el->next)
  2323. {
  2324. c = build_omp_clause (where.lb->location, OMP_CLAUSE_WAIT);
  2325. OMP_CLAUSE_DECL (c) = gfc_convert_expr_to_tree (block, el->expr);
  2326. OMP_CLAUSE_CHAIN (c) = omp_clauses;
  2327. omp_clauses = c;
  2328. }
  2329. }
  2330. if (clauses->num_gangs_expr)
  2331. {
  2332. tree num_gangs_var
  2333. = gfc_convert_expr_to_tree (block, clauses->num_gangs_expr);
  2334. c = build_omp_clause (where.lb->location, OMP_CLAUSE_NUM_GANGS);
  2335. OMP_CLAUSE_NUM_GANGS_EXPR (c) = num_gangs_var;
  2336. omp_clauses = gfc_trans_add_clause (c, omp_clauses);
  2337. }
  2338. if (clauses->num_workers_expr)
  2339. {
  2340. tree num_workers_var
  2341. = gfc_convert_expr_to_tree (block, clauses->num_workers_expr);
  2342. c = build_omp_clause (where.lb->location, OMP_CLAUSE_NUM_WORKERS);
  2343. OMP_CLAUSE_NUM_WORKERS_EXPR (c) = num_workers_var;
  2344. omp_clauses = gfc_trans_add_clause (c, omp_clauses);
  2345. }
  2346. if (clauses->vector_length_expr)
  2347. {
  2348. tree vector_length_var
  2349. = gfc_convert_expr_to_tree (block, clauses->vector_length_expr);
  2350. c = build_omp_clause (where.lb->location, OMP_CLAUSE_VECTOR_LENGTH);
  2351. OMP_CLAUSE_VECTOR_LENGTH_EXPR (c) = vector_length_var;
  2352. omp_clauses = gfc_trans_add_clause (c, omp_clauses);
  2353. }
  2354. if (clauses->vector)
  2355. {
  2356. if (clauses->vector_expr)
  2357. {
  2358. tree vector_var
  2359. = gfc_convert_expr_to_tree (block, clauses->vector_expr);
  2360. c = build_omp_clause (where.lb->location, OMP_CLAUSE_VECTOR);
  2361. OMP_CLAUSE_VECTOR_EXPR (c) = vector_var;
  2362. omp_clauses = gfc_trans_add_clause (c, omp_clauses);
  2363. }
  2364. else
  2365. {
  2366. c = build_omp_clause (where.lb->location, OMP_CLAUSE_VECTOR);
  2367. omp_clauses = gfc_trans_add_clause (c, omp_clauses);
  2368. }
  2369. }
  2370. if (clauses->worker)
  2371. {
  2372. if (clauses->worker_expr)
  2373. {
  2374. tree worker_var
  2375. = gfc_convert_expr_to_tree (block, clauses->worker_expr);
  2376. c = build_omp_clause (where.lb->location, OMP_CLAUSE_WORKER);
  2377. OMP_CLAUSE_WORKER_EXPR (c) = worker_var;
  2378. omp_clauses = gfc_trans_add_clause (c, omp_clauses);
  2379. }
  2380. else
  2381. {
  2382. c = build_omp_clause (where.lb->location, OMP_CLAUSE_WORKER);
  2383. omp_clauses = gfc_trans_add_clause (c, omp_clauses);
  2384. }
  2385. }
  2386. if (clauses->gang)
  2387. {
  2388. if (clauses->gang_expr)
  2389. {
  2390. tree gang_var
  2391. = gfc_convert_expr_to_tree (block, clauses->gang_expr);
  2392. c = build_omp_clause (where.lb->location, OMP_CLAUSE_GANG);
  2393. OMP_CLAUSE_GANG_EXPR (c) = gang_var;
  2394. omp_clauses = gfc_trans_add_clause (c, omp_clauses);
  2395. }
  2396. else
  2397. {
  2398. c = build_omp_clause (where.lb->location, OMP_CLAUSE_GANG);
  2399. omp_clauses = gfc_trans_add_clause (c, omp_clauses);
  2400. }
  2401. }
  2402. return nreverse (omp_clauses);
  2403. }
  2404. /* Like gfc_trans_code, but force creation of a BIND_EXPR around it. */
  2405. static tree
  2406. gfc_trans_omp_code (gfc_code *code, bool force_empty)
  2407. {
  2408. tree stmt;
  2409. pushlevel ();
  2410. stmt = gfc_trans_code (code);
  2411. if (TREE_CODE (stmt) != BIND_EXPR)
  2412. {
  2413. if (!IS_EMPTY_STMT (stmt) || force_empty)
  2414. {
  2415. tree block = poplevel (1, 0);
  2416. stmt = build3_v (BIND_EXPR, NULL, stmt, block);
  2417. }
  2418. else
  2419. poplevel (0, 0);
  2420. }
  2421. else
  2422. poplevel (0, 0);
  2423. return stmt;
  2424. }
  2425. /* Trans OpenACC directives. */
  2426. /* parallel, kernels, data and host_data. */
  2427. static tree
  2428. gfc_trans_oacc_construct (gfc_code *code)
  2429. {
  2430. stmtblock_t block;
  2431. tree stmt, oacc_clauses;
  2432. enum tree_code construct_code;
  2433. switch (code->op)
  2434. {
  2435. case EXEC_OACC_PARALLEL:
  2436. construct_code = OACC_PARALLEL;
  2437. break;
  2438. case EXEC_OACC_KERNELS:
  2439. construct_code = OACC_KERNELS;
  2440. break;
  2441. case EXEC_OACC_DATA:
  2442. construct_code = OACC_DATA;
  2443. break;
  2444. case EXEC_OACC_HOST_DATA:
  2445. construct_code = OACC_HOST_DATA;
  2446. break;
  2447. default:
  2448. gcc_unreachable ();
  2449. }
  2450. gfc_start_block (&block);
  2451. oacc_clauses = gfc_trans_omp_clauses (&block, code->ext.omp_clauses,
  2452. code->loc);
  2453. stmt = gfc_trans_omp_code (code->block->next, true);
  2454. stmt = build2_loc (input_location, construct_code, void_type_node, stmt,
  2455. oacc_clauses);
  2456. gfc_add_expr_to_block (&block, stmt);
  2457. return gfc_finish_block (&block);
  2458. }
  2459. /* update, enter_data, exit_data, cache. */
  2460. static tree
  2461. gfc_trans_oacc_executable_directive (gfc_code *code)
  2462. {
  2463. stmtblock_t block;
  2464. tree stmt, oacc_clauses;
  2465. enum tree_code construct_code;
  2466. switch (code->op)
  2467. {
  2468. case EXEC_OACC_UPDATE:
  2469. construct_code = OACC_UPDATE;
  2470. break;
  2471. case EXEC_OACC_ENTER_DATA:
  2472. construct_code = OACC_ENTER_DATA;
  2473. break;
  2474. case EXEC_OACC_EXIT_DATA:
  2475. construct_code = OACC_EXIT_DATA;
  2476. break;
  2477. case EXEC_OACC_CACHE:
  2478. construct_code = OACC_CACHE;
  2479. break;
  2480. default:
  2481. gcc_unreachable ();
  2482. }
  2483. gfc_start_block (&block);
  2484. oacc_clauses = gfc_trans_omp_clauses (&block, code->ext.omp_clauses,
  2485. code->loc);
  2486. stmt = build1_loc (input_location, construct_code, void_type_node,
  2487. oacc_clauses);
  2488. gfc_add_expr_to_block (&block, stmt);
  2489. return gfc_finish_block (&block);
  2490. }
  2491. static tree
  2492. gfc_trans_oacc_wait_directive (gfc_code *code)
  2493. {
  2494. stmtblock_t block;
  2495. tree stmt, t;
  2496. vec<tree, va_gc> *args;
  2497. int nparms = 0;
  2498. gfc_expr_list *el;
  2499. gfc_omp_clauses *clauses = code->ext.omp_clauses;
  2500. location_t loc = input_location;
  2501. for (el = clauses->wait_list; el; el = el->next)
  2502. nparms++;
  2503. vec_alloc (args, nparms + 2);
  2504. stmt = builtin_decl_explicit (BUILT_IN_GOACC_WAIT);
  2505. gfc_start_block (&block);
  2506. if (clauses->async_expr)
  2507. t = gfc_convert_expr_to_tree (&block, clauses->async_expr);
  2508. else
  2509. t = build_int_cst (integer_type_node, -2);
  2510. args->quick_push (t);
  2511. args->quick_push (build_int_cst (integer_type_node, nparms));
  2512. for (el = clauses->wait_list; el; el = el->next)
  2513. args->quick_push (gfc_convert_expr_to_tree (&block, el->expr));
  2514. stmt = build_call_expr_loc_vec (loc, stmt, args);
  2515. gfc_add_expr_to_block (&block, stmt);
  2516. vec_free (args);
  2517. return gfc_finish_block (&block);
  2518. }
  2519. static tree gfc_trans_omp_sections (gfc_code *, gfc_omp_clauses *);
  2520. static tree gfc_trans_omp_workshare (gfc_code *, gfc_omp_clauses *);
  2521. static tree
  2522. gfc_trans_omp_atomic (gfc_code *code)
  2523. {
  2524. gfc_code *atomic_code = code;
  2525. gfc_se lse;
  2526. gfc_se rse;
  2527. gfc_se vse;
  2528. gfc_expr *expr2, *e;
  2529. gfc_symbol *var;
  2530. stmtblock_t block;
  2531. tree lhsaddr, type, rhs, x;
  2532. enum tree_code op = ERROR_MARK;
  2533. enum tree_code aop = OMP_ATOMIC;
  2534. bool var_on_left = false;
  2535. bool seq_cst = (atomic_code->ext.omp_atomic & GFC_OMP_ATOMIC_SEQ_CST) != 0;
  2536. code = code->block->next;
  2537. gcc_assert (code->op == EXEC_ASSIGN);
  2538. var = code->expr1->symtree->n.sym;
  2539. gfc_init_se (&lse, NULL);
  2540. gfc_init_se (&rse, NULL);
  2541. gfc_init_se (&vse, NULL);
  2542. gfc_start_block (&block);
  2543. expr2 = code->expr2;
  2544. if (expr2->expr_type == EXPR_FUNCTION
  2545. && expr2->value.function.isym->id == GFC_ISYM_CONVERSION)
  2546. expr2 = expr2->value.function.actual->expr;
  2547. switch (atomic_code->ext.omp_atomic & GFC_OMP_ATOMIC_MASK)
  2548. {
  2549. case GFC_OMP_ATOMIC_READ:
  2550. gfc_conv_expr (&vse, code->expr1);
  2551. gfc_add_block_to_block (&block, &vse.pre);
  2552. gfc_conv_expr (&lse, expr2);
  2553. gfc_add_block_to_block (&block, &lse.pre);
  2554. type = TREE_TYPE (lse.expr);
  2555. lhsaddr = gfc_build_addr_expr (NULL, lse.expr);
  2556. x = build1 (OMP_ATOMIC_READ, type, lhsaddr);
  2557. OMP_ATOMIC_SEQ_CST (x) = seq_cst;
  2558. x = convert (TREE_TYPE (vse.expr), x);
  2559. gfc_add_modify (&block, vse.expr, x);
  2560. gfc_add_block_to_block (&block, &lse.pre);
  2561. gfc_add_block_to_block (&block, &rse.pre);
  2562. return gfc_finish_block (&block);
  2563. case GFC_OMP_ATOMIC_CAPTURE:
  2564. aop = OMP_ATOMIC_CAPTURE_NEW;
  2565. if (expr2->expr_type == EXPR_VARIABLE)
  2566. {
  2567. aop = OMP_ATOMIC_CAPTURE_OLD;
  2568. gfc_conv_expr (&vse, code->expr1);
  2569. gfc_add_block_to_block (&block, &vse.pre);
  2570. gfc_conv_expr (&lse, expr2);
  2571. gfc_add_block_to_block (&block, &lse.pre);
  2572. gfc_init_se (&lse, NULL);
  2573. code = code->next;
  2574. var = code->expr1->symtree->n.sym;
  2575. expr2 = code->expr2;
  2576. if (expr2->expr_type == EXPR_FUNCTION
  2577. && expr2->value.function.isym->id == GFC_ISYM_CONVERSION)
  2578. expr2 = expr2->value.function.actual->expr;
  2579. }
  2580. break;
  2581. default:
  2582. break;
  2583. }
  2584. gfc_conv_expr (&lse, code->expr1);
  2585. gfc_add_block_to_block (&block, &lse.pre);
  2586. type = TREE_TYPE (lse.expr);
  2587. lhsaddr = gfc_build_addr_expr (NULL, lse.expr);
  2588. if (((atomic_code->ext.omp_atomic & GFC_OMP_ATOMIC_MASK)
  2589. == GFC_OMP_ATOMIC_WRITE)
  2590. || (atomic_code->ext.omp_atomic & GFC_OMP_ATOMIC_SWAP))
  2591. {
  2592. gfc_conv_expr (&rse, expr2);
  2593. gfc_add_block_to_block (&block, &rse.pre);
  2594. }
  2595. else if (expr2->expr_type == EXPR_OP)
  2596. {
  2597. gfc_expr *e;
  2598. switch (expr2->value.op.op)
  2599. {
  2600. case INTRINSIC_PLUS:
  2601. op = PLUS_EXPR;
  2602. break;
  2603. case INTRINSIC_TIMES:
  2604. op = MULT_EXPR;
  2605. break;
  2606. case INTRINSIC_MINUS:
  2607. op = MINUS_EXPR;
  2608. break;
  2609. case INTRINSIC_DIVIDE:
  2610. if (expr2->ts.type == BT_INTEGER)
  2611. op = TRUNC_DIV_EXPR;
  2612. else
  2613. op = RDIV_EXPR;
  2614. break;
  2615. case INTRINSIC_AND:
  2616. op = TRUTH_ANDIF_EXPR;
  2617. break;
  2618. case INTRINSIC_OR:
  2619. op = TRUTH_ORIF_EXPR;
  2620. break;
  2621. case INTRINSIC_EQV:
  2622. op = EQ_EXPR;
  2623. break;
  2624. case INTRINSIC_NEQV:
  2625. op = NE_EXPR;
  2626. break;
  2627. default:
  2628. gcc_unreachable ();
  2629. }
  2630. e = expr2->value.op.op1;
  2631. if (e->expr_type == EXPR_FUNCTION
  2632. && e->value.function.isym->id == GFC_ISYM_CONVERSION)
  2633. e = e->value.function.actual->expr;
  2634. if (e->expr_type == EXPR_VARIABLE
  2635. && e->symtree != NULL
  2636. && e->symtree->n.sym == var)
  2637. {
  2638. expr2 = expr2->value.op.op2;
  2639. var_on_left = true;
  2640. }
  2641. else
  2642. {
  2643. e = expr2->value.op.op2;
  2644. if (e->expr_type == EXPR_FUNCTION
  2645. && e->value.function.isym->id == GFC_ISYM_CONVERSION)
  2646. e = e->value.function.actual->expr;
  2647. gcc_assert (e->expr_type == EXPR_VARIABLE
  2648. && e->symtree != NULL
  2649. && e->symtree->n.sym == var);
  2650. expr2 = expr2->value.op.op1;
  2651. var_on_left = false;
  2652. }
  2653. gfc_conv_expr (&rse, expr2);
  2654. gfc_add_block_to_block (&block, &rse.pre);
  2655. }
  2656. else
  2657. {
  2658. gcc_assert (expr2->expr_type == EXPR_FUNCTION);
  2659. switch (expr2->value.function.isym->id)
  2660. {
  2661. case GFC_ISYM_MIN:
  2662. op = MIN_EXPR;
  2663. break;
  2664. case GFC_ISYM_MAX:
  2665. op = MAX_EXPR;
  2666. break;
  2667. case GFC_ISYM_IAND:
  2668. op = BIT_AND_EXPR;
  2669. break;
  2670. case GFC_ISYM_IOR:
  2671. op = BIT_IOR_EXPR;
  2672. break;
  2673. case GFC_ISYM_IEOR:
  2674. op = BIT_XOR_EXPR;
  2675. break;
  2676. default:
  2677. gcc_unreachable ();
  2678. }
  2679. e = expr2->value.function.actual->expr;
  2680. gcc_assert (e->expr_type == EXPR_VARIABLE
  2681. && e->symtree != NULL
  2682. && e->symtree->n.sym == var);
  2683. gfc_conv_expr (&rse, expr2->value.function.actual->next->expr);
  2684. gfc_add_block_to_block (&block, &rse.pre);
  2685. if (expr2->value.function.actual->next->next != NULL)
  2686. {
  2687. tree accum = gfc_create_var (TREE_TYPE (rse.expr), NULL);
  2688. gfc_actual_arglist *arg;
  2689. gfc_add_modify (&block, accum, rse.expr);
  2690. for (arg = expr2->value.function.actual->next->next; arg;
  2691. arg = arg->next)
  2692. {
  2693. gfc_init_block (&rse.pre);
  2694. gfc_conv_expr (&rse, arg->expr);
  2695. gfc_add_block_to_block (&block, &rse.pre);
  2696. x = fold_build2_loc (input_location, op, TREE_TYPE (accum),
  2697. accum, rse.expr);
  2698. gfc_add_modify (&block, accum, x);
  2699. }
  2700. rse.expr = accum;
  2701. }
  2702. expr2 = expr2->value.function.actual->next->expr;
  2703. }
  2704. lhsaddr = save_expr (lhsaddr);
  2705. if (TREE_CODE (lhsaddr) != SAVE_EXPR
  2706. && (TREE_CODE (lhsaddr) != ADDR_EXPR
  2707. || TREE_CODE (TREE_OPERAND (lhsaddr, 0)) != VAR_DECL))
  2708. {
  2709. /* Make sure LHS is simple enough so that goa_lhs_expr_p can recognize
  2710. it even after unsharing function body. */
  2711. tree var = create_tmp_var_raw (TREE_TYPE (lhsaddr));
  2712. DECL_CONTEXT (var) = current_function_decl;
  2713. lhsaddr = build4 (TARGET_EXPR, TREE_TYPE (lhsaddr), var, lhsaddr,
  2714. NULL_TREE, NULL_TREE);
  2715. }
  2716. rhs = gfc_evaluate_now (rse.expr, &block);
  2717. if (((atomic_code->ext.omp_atomic & GFC_OMP_ATOMIC_MASK)
  2718. == GFC_OMP_ATOMIC_WRITE)
  2719. || (atomic_code->ext.omp_atomic & GFC_OMP_ATOMIC_SWAP))
  2720. x = rhs;
  2721. else
  2722. {
  2723. x = convert (TREE_TYPE (rhs),
  2724. build_fold_indirect_ref_loc (input_location, lhsaddr));
  2725. if (var_on_left)
  2726. x = fold_build2_loc (input_location, op, TREE_TYPE (rhs), x, rhs);
  2727. else
  2728. x = fold_build2_loc (input_location, op, TREE_TYPE (rhs), rhs, x);
  2729. }
  2730. if (TREE_CODE (TREE_TYPE (rhs)) == COMPLEX_TYPE
  2731. && TREE_CODE (type) != COMPLEX_TYPE)
  2732. x = fold_build1_loc (input_location, REALPART_EXPR,
  2733. TREE_TYPE (TREE_TYPE (rhs)), x);
  2734. gfc_add_block_to_block (&block, &lse.pre);
  2735. gfc_add_block_to_block (&block, &rse.pre);
  2736. if (aop == OMP_ATOMIC)
  2737. {
  2738. x = build2_v (OMP_ATOMIC, lhsaddr, convert (type, x));
  2739. OMP_ATOMIC_SEQ_CST (x) = seq_cst;
  2740. gfc_add_expr_to_block (&block, x);
  2741. }
  2742. else
  2743. {
  2744. if (aop == OMP_ATOMIC_CAPTURE_NEW)
  2745. {
  2746. code = code->next;
  2747. expr2 = code->expr2;
  2748. if (expr2->expr_type == EXPR_FUNCTION
  2749. && expr2->value.function.isym->id == GFC_ISYM_CONVERSION)
  2750. expr2 = expr2->value.function.actual->expr;
  2751. gcc_assert (expr2->expr_type == EXPR_VARIABLE);
  2752. gfc_conv_expr (&vse, code->expr1);
  2753. gfc_add_block_to_block (&block, &vse.pre);
  2754. gfc_init_se (&lse, NULL);
  2755. gfc_conv_expr (&lse, expr2);
  2756. gfc_add_block_to_block (&block, &lse.pre);
  2757. }
  2758. x = build2 (aop, type, lhsaddr, convert (type, x));
  2759. OMP_ATOMIC_SEQ_CST (x) = seq_cst;
  2760. x = convert (TREE_TYPE (vse.expr), x);
  2761. gfc_add_modify (&block, vse.expr, x);
  2762. }
  2763. return gfc_finish_block (&block);
  2764. }
  2765. static tree
  2766. gfc_trans_omp_barrier (void)
  2767. {
  2768. tree decl = builtin_decl_explicit (BUILT_IN_GOMP_BARRIER);
  2769. return build_call_expr_loc (input_location, decl, 0);
  2770. }
  2771. static tree
  2772. gfc_trans_omp_cancel (gfc_code *code)
  2773. {
  2774. int mask = 0;
  2775. tree ifc = boolean_true_node;
  2776. stmtblock_t block;
  2777. switch (code->ext.omp_clauses->cancel)
  2778. {
  2779. case OMP_CANCEL_PARALLEL: mask = 1; break;
  2780. case OMP_CANCEL_DO: mask = 2; break;
  2781. case OMP_CANCEL_SECTIONS: mask = 4; break;
  2782. case OMP_CANCEL_TASKGROUP: mask = 8; break;
  2783. default: gcc_unreachable ();
  2784. }
  2785. gfc_start_block (&block);
  2786. if (code->ext.omp_clauses->if_expr)
  2787. {
  2788. gfc_se se;
  2789. tree if_var;
  2790. gfc_init_se (&se, NULL);
  2791. gfc_conv_expr (&se, code->ext.omp_clauses->if_expr);
  2792. gfc_add_block_to_block (&block, &se.pre);
  2793. if_var = gfc_evaluate_now (se.expr, &block);
  2794. gfc_add_block_to_block (&block, &se.post);
  2795. tree type = TREE_TYPE (if_var);
  2796. ifc = fold_build2_loc (input_location, NE_EXPR,
  2797. boolean_type_node, if_var,
  2798. build_zero_cst (type));
  2799. }
  2800. tree decl = builtin_decl_explicit (BUILT_IN_GOMP_CANCEL);
  2801. tree c_bool_type = TREE_TYPE (TREE_TYPE (decl));
  2802. ifc = fold_convert (c_bool_type, ifc);
  2803. gfc_add_expr_to_block (&block,
  2804. build_call_expr_loc (input_location, decl, 2,
  2805. build_int_cst (integer_type_node,
  2806. mask), ifc));
  2807. return gfc_finish_block (&block);
  2808. }
  2809. static tree
  2810. gfc_trans_omp_cancellation_point (gfc_code *code)
  2811. {
  2812. int mask = 0;
  2813. switch (code->ext.omp_clauses->cancel)
  2814. {
  2815. case OMP_CANCEL_PARALLEL: mask = 1; break;
  2816. case OMP_CANCEL_DO: mask = 2; break;
  2817. case OMP_CANCEL_SECTIONS: mask = 4; break;
  2818. case OMP_CANCEL_TASKGROUP: mask = 8; break;
  2819. default: gcc_unreachable ();
  2820. }
  2821. tree decl = builtin_decl_explicit (BUILT_IN_GOMP_CANCELLATION_POINT);
  2822. return build_call_expr_loc (input_location, decl, 1,
  2823. build_int_cst (integer_type_node, mask));
  2824. }
  2825. static tree
  2826. gfc_trans_omp_critical (gfc_code *code)
  2827. {
  2828. tree name = NULL_TREE, stmt;
  2829. if (code->ext.omp_name != NULL)
  2830. name = get_identifier (code->ext.omp_name);
  2831. stmt = gfc_trans_code (code->block->next);
  2832. return build2_loc (input_location, OMP_CRITICAL, void_type_node, stmt, name);
  2833. }
  2834. typedef struct dovar_init_d {
  2835. tree var;
  2836. tree init;
  2837. } dovar_init;
  2838. static tree
  2839. gfc_trans_omp_do (gfc_code *code, gfc_exec_op op, stmtblock_t *pblock,
  2840. gfc_omp_clauses *do_clauses, tree par_clauses)
  2841. {
  2842. gfc_se se;
  2843. tree dovar, stmt, from, to, step, type, init, cond, incr;
  2844. tree count = NULL_TREE, cycle_label, tmp, omp_clauses;
  2845. stmtblock_t block;
  2846. stmtblock_t body;
  2847. gfc_omp_clauses *clauses = code->ext.omp_clauses;
  2848. int i, collapse = clauses->collapse;
  2849. vec<dovar_init> inits = vNULL;
  2850. dovar_init *di;
  2851. unsigned ix;
  2852. if (collapse <= 0)
  2853. collapse = 1;
  2854. code = code->block->next;
  2855. gcc_assert (code->op == EXEC_DO);
  2856. init = make_tree_vec (collapse);
  2857. cond = make_tree_vec (collapse);
  2858. incr = make_tree_vec (collapse);
  2859. if (pblock == NULL)
  2860. {
  2861. gfc_start_block (&block);
  2862. pblock = &block;
  2863. }
  2864. omp_clauses = gfc_trans_omp_clauses (pblock, do_clauses, code->loc);
  2865. for (i = 0; i < collapse; i++)
  2866. {
  2867. int simple = 0;
  2868. int dovar_found = 0;
  2869. tree dovar_decl;
  2870. if (clauses)
  2871. {
  2872. gfc_omp_namelist *n = NULL;
  2873. if (op != EXEC_OMP_DISTRIBUTE)
  2874. for (n = clauses->lists[(op == EXEC_OMP_SIMD && collapse == 1)
  2875. ? OMP_LIST_LINEAR : OMP_LIST_LASTPRIVATE];
  2876. n != NULL; n = n->next)
  2877. if (code->ext.iterator->var->symtree->n.sym == n->sym)
  2878. break;
  2879. if (n != NULL)
  2880. dovar_found = 1;
  2881. else if (n == NULL && op != EXEC_OMP_SIMD)
  2882. for (n = clauses->lists[OMP_LIST_PRIVATE]; n != NULL; n = n->next)
  2883. if (code->ext.iterator->var->symtree->n.sym == n->sym)
  2884. break;
  2885. if (n != NULL)
  2886. dovar_found++;
  2887. }
  2888. /* Evaluate all the expressions in the iterator. */
  2889. gfc_init_se (&se, NULL);
  2890. gfc_conv_expr_lhs (&se, code->ext.iterator->var);
  2891. gfc_add_block_to_block (pblock, &se.pre);
  2892. dovar = se.expr;
  2893. type = TREE_TYPE (dovar);
  2894. gcc_assert (TREE_CODE (type) == INTEGER_TYPE);
  2895. gfc_init_se (&se, NULL);
  2896. gfc_conv_expr_val (&se, code->ext.iterator->start);
  2897. gfc_add_block_to_block (pblock, &se.pre);
  2898. from = gfc_evaluate_now (se.expr, pblock);
  2899. gfc_init_se (&se, NULL);
  2900. gfc_conv_expr_val (&se, code->ext.iterator->end);
  2901. gfc_add_block_to_block (pblock, &se.pre);
  2902. to = gfc_evaluate_now (se.expr, pblock);
  2903. gfc_init_se (&se, NULL);
  2904. gfc_conv_expr_val (&se, code->ext.iterator->step);
  2905. gfc_add_block_to_block (pblock, &se.pre);
  2906. step = gfc_evaluate_now (se.expr, pblock);
  2907. dovar_decl = dovar;
  2908. /* Special case simple loops. */
  2909. if (TREE_CODE (dovar) == VAR_DECL)
  2910. {
  2911. if (integer_onep (step))
  2912. simple = 1;
  2913. else if (tree_int_cst_equal (step, integer_minus_one_node))
  2914. simple = -1;
  2915. }
  2916. else
  2917. dovar_decl
  2918. = gfc_trans_omp_variable (code->ext.iterator->var->symtree->n.sym,
  2919. false);
  2920. /* Loop body. */
  2921. if (simple)
  2922. {
  2923. TREE_VEC_ELT (init, i) = build2_v (MODIFY_EXPR, dovar, from);
  2924. /* The condition should not be folded. */
  2925. TREE_VEC_ELT (cond, i) = build2_loc (input_location, simple > 0
  2926. ? LE_EXPR : GE_EXPR,
  2927. boolean_type_node, dovar, to);
  2928. TREE_VEC_ELT (incr, i) = fold_build2_loc (input_location, PLUS_EXPR,
  2929. type, dovar, step);
  2930. TREE_VEC_ELT (incr, i) = fold_build2_loc (input_location,
  2931. MODIFY_EXPR,
  2932. type, dovar,
  2933. TREE_VEC_ELT (incr, i));
  2934. }
  2935. else
  2936. {
  2937. /* STEP is not 1 or -1. Use:
  2938. for (count = 0; count < (to + step - from) / step; count++)
  2939. {
  2940. dovar = from + count * step;
  2941. body;
  2942. cycle_label:;
  2943. } */
  2944. tmp = fold_build2_loc (input_location, MINUS_EXPR, type, step, from);
  2945. tmp = fold_build2_loc (input_location, PLUS_EXPR, type, to, tmp);
  2946. tmp = fold_build2_loc (input_location, TRUNC_DIV_EXPR, type, tmp,
  2947. step);
  2948. tmp = gfc_evaluate_now (tmp, pblock);
  2949. count = gfc_create_var (type, "count");
  2950. TREE_VEC_ELT (init, i) = build2_v (MODIFY_EXPR, count,
  2951. build_int_cst (type, 0));
  2952. /* The condition should not be folded. */
  2953. TREE_VEC_ELT (cond, i) = build2_loc (input_location, LT_EXPR,
  2954. boolean_type_node,
  2955. count, tmp);
  2956. TREE_VEC_ELT (incr, i) = fold_build2_loc (input_location, PLUS_EXPR,
  2957. type, count,
  2958. build_int_cst (type, 1));
  2959. TREE_VEC_ELT (incr, i) = fold_build2_loc (input_location,
  2960. MODIFY_EXPR, type, count,
  2961. TREE_VEC_ELT (incr, i));
  2962. /* Initialize DOVAR. */
  2963. tmp = fold_build2_loc (input_location, MULT_EXPR, type, count, step);
  2964. tmp = fold_build2_loc (input_location, PLUS_EXPR, type, from, tmp);
  2965. dovar_init e = {dovar, tmp};
  2966. inits.safe_push (e);
  2967. }
  2968. if (dovar_found == 2
  2969. && op == EXEC_OMP_SIMD
  2970. && collapse == 1
  2971. && !simple)
  2972. {
  2973. for (tmp = omp_clauses; tmp; tmp = OMP_CLAUSE_CHAIN (tmp))
  2974. if (OMP_CLAUSE_CODE (tmp) == OMP_CLAUSE_LINEAR
  2975. && OMP_CLAUSE_DECL (tmp) == dovar)
  2976. {
  2977. OMP_CLAUSE_LINEAR_NO_COPYIN (tmp) = 1;
  2978. break;
  2979. }
  2980. }
  2981. if (!dovar_found)
  2982. {
  2983. if (op == EXEC_OMP_SIMD)
  2984. {
  2985. if (collapse == 1)
  2986. {
  2987. tmp = build_omp_clause (input_location, OMP_CLAUSE_LINEAR);
  2988. OMP_CLAUSE_LINEAR_STEP (tmp) = step;
  2989. OMP_CLAUSE_LINEAR_NO_COPYIN (tmp) = 1;
  2990. }
  2991. else
  2992. tmp = build_omp_clause (input_location, OMP_CLAUSE_LASTPRIVATE);
  2993. if (!simple)
  2994. dovar_found = 2;
  2995. }
  2996. else
  2997. tmp = build_omp_clause (input_location, OMP_CLAUSE_PRIVATE);
  2998. OMP_CLAUSE_DECL (tmp) = dovar_decl;
  2999. omp_clauses = gfc_trans_add_clause (tmp, omp_clauses);
  3000. }
  3001. if (dovar_found == 2)
  3002. {
  3003. tree c = NULL;
  3004. tmp = NULL;
  3005. if (!simple)
  3006. {
  3007. /* If dovar is lastprivate, but different counter is used,
  3008. dovar += step needs to be added to
  3009. OMP_CLAUSE_LASTPRIVATE_STMT, otherwise the copied dovar
  3010. will have the value on entry of the last loop, rather
  3011. than value after iterator increment. */
  3012. tmp = gfc_evaluate_now (step, pblock);
  3013. tmp = fold_build2_loc (input_location, PLUS_EXPR, type, dovar,
  3014. tmp);
  3015. tmp = fold_build2_loc (input_location, MODIFY_EXPR, type,
  3016. dovar, tmp);
  3017. for (c = omp_clauses; c ; c = OMP_CLAUSE_CHAIN (c))
  3018. if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
  3019. && OMP_CLAUSE_DECL (c) == dovar_decl)
  3020. {
  3021. OMP_CLAUSE_LASTPRIVATE_STMT (c) = tmp;
  3022. break;
  3023. }
  3024. else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
  3025. && OMP_CLAUSE_DECL (c) == dovar_decl)
  3026. {
  3027. OMP_CLAUSE_LINEAR_STMT (c) = tmp;
  3028. break;
  3029. }
  3030. }
  3031. if (c == NULL && op == EXEC_OMP_DO && par_clauses != NULL)
  3032. {
  3033. for (c = par_clauses; c ; c = OMP_CLAUSE_CHAIN (c))
  3034. if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
  3035. && OMP_CLAUSE_DECL (c) == dovar_decl)
  3036. {
  3037. tree l = build_omp_clause (input_location,
  3038. OMP_CLAUSE_LASTPRIVATE);
  3039. OMP_CLAUSE_DECL (l) = dovar_decl;
  3040. OMP_CLAUSE_CHAIN (l) = omp_clauses;
  3041. OMP_CLAUSE_LASTPRIVATE_STMT (l) = tmp;
  3042. omp_clauses = l;
  3043. OMP_CLAUSE_SET_CODE (c, OMP_CLAUSE_SHARED);
  3044. break;
  3045. }
  3046. }
  3047. gcc_assert (simple || c != NULL);
  3048. }
  3049. if (!simple)
  3050. {
  3051. if (op != EXEC_OMP_SIMD)
  3052. tmp = build_omp_clause (input_location, OMP_CLAUSE_PRIVATE);
  3053. else if (collapse == 1)
  3054. {
  3055. tmp = build_omp_clause (input_location, OMP_CLAUSE_LINEAR);
  3056. OMP_CLAUSE_LINEAR_STEP (tmp) = build_int_cst (type, 1);
  3057. OMP_CLAUSE_LINEAR_NO_COPYIN (tmp) = 1;
  3058. OMP_CLAUSE_LINEAR_NO_COPYOUT (tmp) = 1;
  3059. }
  3060. else
  3061. tmp = build_omp_clause (input_location, OMP_CLAUSE_LASTPRIVATE);
  3062. OMP_CLAUSE_DECL (tmp) = count;
  3063. omp_clauses = gfc_trans_add_clause (tmp, omp_clauses);
  3064. }
  3065. if (i + 1 < collapse)
  3066. code = code->block->next;
  3067. }
  3068. if (pblock != &block)
  3069. {
  3070. pushlevel ();
  3071. gfc_start_block (&block);
  3072. }
  3073. gfc_start_block (&body);
  3074. FOR_EACH_VEC_ELT (inits, ix, di)
  3075. gfc_add_modify (&body, di->var, di->init);
  3076. inits.release ();
  3077. /* Cycle statement is implemented with a goto. Exit statement must not be
  3078. present for this loop. */
  3079. cycle_label = gfc_build_label_decl (NULL_TREE);
  3080. /* Put these labels where they can be found later. */
  3081. code->cycle_label = cycle_label;
  3082. code->exit_label = NULL_TREE;
  3083. /* Main loop body. */
  3084. tmp = gfc_trans_omp_code (code->block->next, true);
  3085. gfc_add_expr_to_block (&body, tmp);
  3086. /* Label for cycle statements (if needed). */
  3087. if (TREE_USED (cycle_label))
  3088. {
  3089. tmp = build1_v (LABEL_EXPR, cycle_label);
  3090. gfc_add_expr_to_block (&body, tmp);
  3091. }
  3092. /* End of loop body. */
  3093. switch (op)
  3094. {
  3095. case EXEC_OMP_SIMD: stmt = make_node (OMP_SIMD); break;
  3096. case EXEC_OMP_DO: stmt = make_node (OMP_FOR); break;
  3097. case EXEC_OMP_DISTRIBUTE: stmt = make_node (OMP_DISTRIBUTE); break;
  3098. case EXEC_OACC_LOOP: stmt = make_node (OACC_LOOP); break;
  3099. default: gcc_unreachable ();
  3100. }
  3101. TREE_TYPE (stmt) = void_type_node;
  3102. OMP_FOR_BODY (stmt) = gfc_finish_block (&body);
  3103. OMP_FOR_CLAUSES (stmt) = omp_clauses;
  3104. OMP_FOR_INIT (stmt) = init;
  3105. OMP_FOR_COND (stmt) = cond;
  3106. OMP_FOR_INCR (stmt) = incr;
  3107. gfc_add_expr_to_block (&block, stmt);
  3108. return gfc_finish_block (&block);
  3109. }
  3110. /* parallel loop and kernels loop. */
  3111. static tree
  3112. gfc_trans_oacc_combined_directive (gfc_code *code)
  3113. {
  3114. stmtblock_t block, *pblock = NULL;
  3115. gfc_omp_clauses construct_clauses, loop_clauses;
  3116. tree stmt, oacc_clauses = NULL_TREE;
  3117. enum tree_code construct_code;
  3118. switch (code->op)
  3119. {
  3120. case EXEC_OACC_PARALLEL_LOOP:
  3121. construct_code = OACC_PARALLEL;
  3122. break;
  3123. case EXEC_OACC_KERNELS_LOOP:
  3124. construct_code = OACC_KERNELS;
  3125. break;
  3126. default:
  3127. gcc_unreachable ();
  3128. }
  3129. gfc_start_block (&block);
  3130. memset (&loop_clauses, 0, sizeof (loop_clauses));
  3131. if (code->ext.omp_clauses != NULL)
  3132. {
  3133. memcpy (&construct_clauses, code->ext.omp_clauses,
  3134. sizeof (construct_clauses));
  3135. loop_clauses.collapse = construct_clauses.collapse;
  3136. loop_clauses.gang = construct_clauses.gang;
  3137. loop_clauses.vector = construct_clauses.vector;
  3138. loop_clauses.worker = construct_clauses.worker;
  3139. loop_clauses.seq = construct_clauses.seq;
  3140. loop_clauses.independent = construct_clauses.independent;
  3141. construct_clauses.collapse = 0;
  3142. construct_clauses.gang = false;
  3143. construct_clauses.vector = false;
  3144. construct_clauses.worker = false;
  3145. construct_clauses.seq = false;
  3146. construct_clauses.independent = false;
  3147. oacc_clauses = gfc_trans_omp_clauses (&block, &construct_clauses,
  3148. code->loc);
  3149. }
  3150. if (!loop_clauses.seq)
  3151. pblock = &block;
  3152. else
  3153. pushlevel ();
  3154. stmt = gfc_trans_omp_do (code, EXEC_OACC_LOOP, pblock, &loop_clauses, NULL);
  3155. if (TREE_CODE (stmt) != BIND_EXPR)
  3156. stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0));
  3157. else
  3158. poplevel (0, 0);
  3159. stmt = build2_loc (input_location, construct_code, void_type_node, stmt,
  3160. oacc_clauses);
  3161. if (code->op == EXEC_OACC_KERNELS_LOOP)
  3162. OACC_KERNELS_COMBINED (stmt) = 1;
  3163. else
  3164. OACC_PARALLEL_COMBINED (stmt) = 1;
  3165. gfc_add_expr_to_block (&block, stmt);
  3166. return gfc_finish_block (&block);
  3167. }
  3168. static tree
  3169. gfc_trans_omp_flush (void)
  3170. {
  3171. tree decl = builtin_decl_explicit (BUILT_IN_SYNC_SYNCHRONIZE);
  3172. return build_call_expr_loc (input_location, decl, 0);
  3173. }
  3174. static tree
  3175. gfc_trans_omp_master (gfc_code *code)
  3176. {
  3177. tree stmt = gfc_trans_code (code->block->next);
  3178. if (IS_EMPTY_STMT (stmt))
  3179. return stmt;
  3180. return build1_v (OMP_MASTER, stmt);
  3181. }
  3182. static tree
  3183. gfc_trans_omp_ordered (gfc_code *code)
  3184. {
  3185. return build1_v (OMP_ORDERED, gfc_trans_code (code->block->next));
  3186. }
  3187. static tree
  3188. gfc_trans_omp_parallel (gfc_code *code)
  3189. {
  3190. stmtblock_t block;
  3191. tree stmt, omp_clauses;
  3192. gfc_start_block (&block);
  3193. omp_clauses = gfc_trans_omp_clauses (&block, code->ext.omp_clauses,
  3194. code->loc);
  3195. stmt = gfc_trans_omp_code (code->block->next, true);
  3196. stmt = build2_loc (input_location, OMP_PARALLEL, void_type_node, stmt,
  3197. omp_clauses);
  3198. gfc_add_expr_to_block (&block, stmt);
  3199. return gfc_finish_block (&block);
  3200. }
  3201. enum
  3202. {
  3203. GFC_OMP_SPLIT_SIMD,
  3204. GFC_OMP_SPLIT_DO,
  3205. GFC_OMP_SPLIT_PARALLEL,
  3206. GFC_OMP_SPLIT_DISTRIBUTE,
  3207. GFC_OMP_SPLIT_TEAMS,
  3208. GFC_OMP_SPLIT_TARGET,
  3209. GFC_OMP_SPLIT_NUM
  3210. };
  3211. enum
  3212. {
  3213. GFC_OMP_MASK_SIMD = (1 << GFC_OMP_SPLIT_SIMD),
  3214. GFC_OMP_MASK_DO = (1 << GFC_OMP_SPLIT_DO),
  3215. GFC_OMP_MASK_PARALLEL = (1 << GFC_OMP_SPLIT_PARALLEL),
  3216. GFC_OMP_MASK_DISTRIBUTE = (1 << GFC_OMP_SPLIT_DISTRIBUTE),
  3217. GFC_OMP_MASK_TEAMS = (1 << GFC_OMP_SPLIT_TEAMS),
  3218. GFC_OMP_MASK_TARGET = (1 << GFC_OMP_SPLIT_TARGET)
  3219. };
  3220. static void
  3221. gfc_split_omp_clauses (gfc_code *code,
  3222. gfc_omp_clauses clausesa[GFC_OMP_SPLIT_NUM])
  3223. {
  3224. int mask = 0, innermost = 0;
  3225. memset (clausesa, 0, GFC_OMP_SPLIT_NUM * sizeof (gfc_omp_clauses));
  3226. switch (code->op)
  3227. {
  3228. case EXEC_OMP_DISTRIBUTE:
  3229. innermost = GFC_OMP_SPLIT_DISTRIBUTE;
  3230. break;
  3231. case EXEC_OMP_DISTRIBUTE_PARALLEL_DO:
  3232. mask = GFC_OMP_MASK_DISTRIBUTE | GFC_OMP_MASK_PARALLEL | GFC_OMP_MASK_DO;
  3233. innermost = GFC_OMP_SPLIT_DO;
  3234. break;
  3235. case EXEC_OMP_DISTRIBUTE_PARALLEL_DO_SIMD:
  3236. mask = GFC_OMP_MASK_DISTRIBUTE | GFC_OMP_MASK_PARALLEL
  3237. | GFC_OMP_MASK_DO | GFC_OMP_MASK_SIMD;
  3238. innermost = GFC_OMP_SPLIT_SIMD;
  3239. break;
  3240. case EXEC_OMP_DISTRIBUTE_SIMD:
  3241. mask = GFC_OMP_MASK_DISTRIBUTE | GFC_OMP_MASK_SIMD;
  3242. innermost = GFC_OMP_SPLIT_SIMD;
  3243. break;
  3244. case EXEC_OMP_DO:
  3245. innermost = GFC_OMP_SPLIT_DO;
  3246. break;
  3247. case EXEC_OMP_DO_SIMD:
  3248. mask = GFC_OMP_MASK_DO | GFC_OMP_MASK_SIMD;
  3249. innermost = GFC_OMP_SPLIT_SIMD;
  3250. break;
  3251. case EXEC_OMP_PARALLEL:
  3252. innermost = GFC_OMP_SPLIT_PARALLEL;
  3253. break;
  3254. case EXEC_OMP_PARALLEL_DO:
  3255. mask = GFC_OMP_MASK_PARALLEL | GFC_OMP_MASK_DO;
  3256. innermost = GFC_OMP_SPLIT_DO;
  3257. break;
  3258. case EXEC_OMP_PARALLEL_DO_SIMD:
  3259. mask = GFC_OMP_MASK_PARALLEL | GFC_OMP_MASK_DO | GFC_OMP_MASK_SIMD;
  3260. innermost = GFC_OMP_SPLIT_SIMD;
  3261. break;
  3262. case EXEC_OMP_SIMD:
  3263. innermost = GFC_OMP_SPLIT_SIMD;
  3264. break;
  3265. case EXEC_OMP_TARGET:
  3266. innermost = GFC_OMP_SPLIT_TARGET;
  3267. break;
  3268. case EXEC_OMP_TARGET_TEAMS:
  3269. mask = GFC_OMP_MASK_TARGET | GFC_OMP_MASK_TEAMS;
  3270. innermost = GFC_OMP_SPLIT_TEAMS;
  3271. break;
  3272. case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE:
  3273. mask = GFC_OMP_MASK_TARGET | GFC_OMP_MASK_TEAMS
  3274. | GFC_OMP_MASK_DISTRIBUTE;
  3275. innermost = GFC_OMP_SPLIT_DISTRIBUTE;
  3276. break;
  3277. case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO:
  3278. mask = GFC_OMP_MASK_TARGET | GFC_OMP_MASK_TEAMS | GFC_OMP_MASK_DISTRIBUTE
  3279. | GFC_OMP_MASK_PARALLEL | GFC_OMP_MASK_DO;
  3280. innermost = GFC_OMP_SPLIT_DO;
  3281. break;
  3282. case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
  3283. mask = GFC_OMP_MASK_TARGET | GFC_OMP_MASK_TEAMS | GFC_OMP_MASK_DISTRIBUTE
  3284. | GFC_OMP_MASK_PARALLEL | GFC_OMP_MASK_DO | GFC_OMP_MASK_SIMD;
  3285. innermost = GFC_OMP_SPLIT_SIMD;
  3286. break;
  3287. case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD:
  3288. mask = GFC_OMP_MASK_TARGET | GFC_OMP_MASK_TEAMS
  3289. | GFC_OMP_MASK_DISTRIBUTE | GFC_OMP_MASK_SIMD;
  3290. innermost = GFC_OMP_SPLIT_SIMD;
  3291. break;
  3292. case EXEC_OMP_TEAMS:
  3293. innermost = GFC_OMP_SPLIT_TEAMS;
  3294. break;
  3295. case EXEC_OMP_TEAMS_DISTRIBUTE:
  3296. mask = GFC_OMP_MASK_TEAMS | GFC_OMP_MASK_DISTRIBUTE;
  3297. innermost = GFC_OMP_SPLIT_DISTRIBUTE;
  3298. break;
  3299. case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO:
  3300. mask = GFC_OMP_MASK_TEAMS | GFC_OMP_MASK_DISTRIBUTE
  3301. | GFC_OMP_MASK_PARALLEL | GFC_OMP_MASK_DO;
  3302. innermost = GFC_OMP_SPLIT_DO;
  3303. break;
  3304. case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
  3305. mask = GFC_OMP_MASK_TEAMS | GFC_OMP_MASK_DISTRIBUTE
  3306. | GFC_OMP_MASK_PARALLEL | GFC_OMP_MASK_DO | GFC_OMP_MASK_SIMD;
  3307. innermost = GFC_OMP_SPLIT_SIMD;
  3308. break;
  3309. case EXEC_OMP_TEAMS_DISTRIBUTE_SIMD:
  3310. mask = GFC_OMP_MASK_TEAMS | GFC_OMP_MASK_DISTRIBUTE | GFC_OMP_MASK_SIMD;
  3311. innermost = GFC_OMP_SPLIT_SIMD;
  3312. break;
  3313. default:
  3314. gcc_unreachable ();
  3315. }
  3316. if (mask == 0)
  3317. {
  3318. clausesa[innermost] = *code->ext.omp_clauses;
  3319. return;
  3320. }
  3321. if (code->ext.omp_clauses != NULL)
  3322. {
  3323. if (mask & GFC_OMP_MASK_TARGET)
  3324. {
  3325. /* First the clauses that are unique to some constructs. */
  3326. clausesa[GFC_OMP_SPLIT_TARGET].lists[OMP_LIST_MAP]
  3327. = code->ext.omp_clauses->lists[OMP_LIST_MAP];
  3328. clausesa[GFC_OMP_SPLIT_TARGET].device
  3329. = code->ext.omp_clauses->device;
  3330. }
  3331. if (mask & GFC_OMP_MASK_TEAMS)
  3332. {
  3333. /* First the clauses that are unique to some constructs. */
  3334. clausesa[GFC_OMP_SPLIT_TEAMS].num_teams
  3335. = code->ext.omp_clauses->num_teams;
  3336. clausesa[GFC_OMP_SPLIT_TEAMS].thread_limit
  3337. = code->ext.omp_clauses->thread_limit;
  3338. /* Shared and default clauses are allowed on parallel and teams. */
  3339. clausesa[GFC_OMP_SPLIT_TEAMS].lists[OMP_LIST_SHARED]
  3340. = code->ext.omp_clauses->lists[OMP_LIST_SHARED];
  3341. clausesa[GFC_OMP_SPLIT_TEAMS].default_sharing
  3342. = code->ext.omp_clauses->default_sharing;
  3343. }
  3344. if (mask & GFC_OMP_MASK_DISTRIBUTE)
  3345. {
  3346. /* First the clauses that are unique to some constructs. */
  3347. clausesa[GFC_OMP_SPLIT_DISTRIBUTE].dist_sched_kind
  3348. = code->ext.omp_clauses->dist_sched_kind;
  3349. clausesa[GFC_OMP_SPLIT_DISTRIBUTE].dist_chunk_size
  3350. = code->ext.omp_clauses->dist_chunk_size;
  3351. /* Duplicate collapse. */
  3352. clausesa[GFC_OMP_SPLIT_DISTRIBUTE].collapse
  3353. = code->ext.omp_clauses->collapse;
  3354. }
  3355. if (mask & GFC_OMP_MASK_PARALLEL)
  3356. {
  3357. /* First the clauses that are unique to some constructs. */
  3358. clausesa[GFC_OMP_SPLIT_PARALLEL].lists[OMP_LIST_COPYIN]
  3359. = code->ext.omp_clauses->lists[OMP_LIST_COPYIN];
  3360. clausesa[GFC_OMP_SPLIT_PARALLEL].num_threads
  3361. = code->ext.omp_clauses->num_threads;
  3362. clausesa[GFC_OMP_SPLIT_PARALLEL].proc_bind
  3363. = code->ext.omp_clauses->proc_bind;
  3364. /* Shared and default clauses are allowed on parallel and teams. */
  3365. clausesa[GFC_OMP_SPLIT_PARALLEL].lists[OMP_LIST_SHARED]
  3366. = code->ext.omp_clauses->lists[OMP_LIST_SHARED];
  3367. clausesa[GFC_OMP_SPLIT_PARALLEL].default_sharing
  3368. = code->ext.omp_clauses->default_sharing;
  3369. }
  3370. if (mask & GFC_OMP_MASK_DO)
  3371. {
  3372. /* First the clauses that are unique to some constructs. */
  3373. clausesa[GFC_OMP_SPLIT_DO].ordered
  3374. = code->ext.omp_clauses->ordered;
  3375. clausesa[GFC_OMP_SPLIT_DO].sched_kind
  3376. = code->ext.omp_clauses->sched_kind;
  3377. clausesa[GFC_OMP_SPLIT_DO].chunk_size
  3378. = code->ext.omp_clauses->chunk_size;
  3379. clausesa[GFC_OMP_SPLIT_DO].nowait
  3380. = code->ext.omp_clauses->nowait;
  3381. /* Duplicate collapse. */
  3382. clausesa[GFC_OMP_SPLIT_DO].collapse
  3383. = code->ext.omp_clauses->collapse;
  3384. }
  3385. if (mask & GFC_OMP_MASK_SIMD)
  3386. {
  3387. clausesa[GFC_OMP_SPLIT_SIMD].safelen_expr
  3388. = code->ext.omp_clauses->safelen_expr;
  3389. clausesa[GFC_OMP_SPLIT_SIMD].lists[OMP_LIST_LINEAR]
  3390. = code->ext.omp_clauses->lists[OMP_LIST_LINEAR];
  3391. clausesa[GFC_OMP_SPLIT_SIMD].lists[OMP_LIST_ALIGNED]
  3392. = code->ext.omp_clauses->lists[OMP_LIST_ALIGNED];
  3393. /* Duplicate collapse. */
  3394. clausesa[GFC_OMP_SPLIT_SIMD].collapse
  3395. = code->ext.omp_clauses->collapse;
  3396. }
  3397. /* Private clause is supported on all constructs but target,
  3398. it is enough to put it on the innermost one. For
  3399. !$ omp do put it on parallel though,
  3400. as that's what we did for OpenMP 3.1. */
  3401. clausesa[innermost == GFC_OMP_SPLIT_DO
  3402. ? (int) GFC_OMP_SPLIT_PARALLEL
  3403. : innermost].lists[OMP_LIST_PRIVATE]
  3404. = code->ext.omp_clauses->lists[OMP_LIST_PRIVATE];
  3405. /* Firstprivate clause is supported on all constructs but
  3406. target and simd. Put it on the outermost of those and
  3407. duplicate on parallel. */
  3408. if (mask & GFC_OMP_MASK_TEAMS)
  3409. clausesa[GFC_OMP_SPLIT_TEAMS].lists[OMP_LIST_FIRSTPRIVATE]
  3410. = code->ext.omp_clauses->lists[OMP_LIST_FIRSTPRIVATE];
  3411. else if (mask & GFC_OMP_MASK_DISTRIBUTE)
  3412. clausesa[GFC_OMP_SPLIT_DISTRIBUTE].lists[OMP_LIST_FIRSTPRIVATE]
  3413. = code->ext.omp_clauses->lists[OMP_LIST_FIRSTPRIVATE];
  3414. if (mask & GFC_OMP_MASK_PARALLEL)
  3415. clausesa[GFC_OMP_SPLIT_PARALLEL].lists[OMP_LIST_FIRSTPRIVATE]
  3416. = code->ext.omp_clauses->lists[OMP_LIST_FIRSTPRIVATE];
  3417. else if (mask & GFC_OMP_MASK_DO)
  3418. clausesa[GFC_OMP_SPLIT_DO].lists[OMP_LIST_FIRSTPRIVATE]
  3419. = code->ext.omp_clauses->lists[OMP_LIST_FIRSTPRIVATE];
  3420. /* Lastprivate is allowed on do and simd. In
  3421. parallel do{, simd} we actually want to put it on
  3422. parallel rather than do. */
  3423. if (mask & GFC_OMP_MASK_PARALLEL)
  3424. clausesa[GFC_OMP_SPLIT_PARALLEL].lists[OMP_LIST_LASTPRIVATE]
  3425. = code->ext.omp_clauses->lists[OMP_LIST_LASTPRIVATE];
  3426. else if (mask & GFC_OMP_MASK_DO)
  3427. clausesa[GFC_OMP_SPLIT_DO].lists[OMP_LIST_LASTPRIVATE]
  3428. = code->ext.omp_clauses->lists[OMP_LIST_LASTPRIVATE];
  3429. if (mask & GFC_OMP_MASK_SIMD)
  3430. clausesa[GFC_OMP_SPLIT_SIMD].lists[OMP_LIST_LASTPRIVATE]
  3431. = code->ext.omp_clauses->lists[OMP_LIST_LASTPRIVATE];
  3432. /* Reduction is allowed on simd, do, parallel and teams.
  3433. Duplicate it on all of them, but omit on do if
  3434. parallel is present. */
  3435. if (mask & GFC_OMP_MASK_TEAMS)
  3436. clausesa[GFC_OMP_SPLIT_TEAMS].lists[OMP_LIST_REDUCTION]
  3437. = code->ext.omp_clauses->lists[OMP_LIST_REDUCTION];
  3438. if (mask & GFC_OMP_MASK_PARALLEL)
  3439. clausesa[GFC_OMP_SPLIT_PARALLEL].lists[OMP_LIST_REDUCTION]
  3440. = code->ext.omp_clauses->lists[OMP_LIST_REDUCTION];
  3441. else if (mask & GFC_OMP_MASK_DO)
  3442. clausesa[GFC_OMP_SPLIT_DO].lists[OMP_LIST_REDUCTION]
  3443. = code->ext.omp_clauses->lists[OMP_LIST_REDUCTION];
  3444. if (mask & GFC_OMP_MASK_SIMD)
  3445. clausesa[GFC_OMP_SPLIT_SIMD].lists[OMP_LIST_REDUCTION]
  3446. = code->ext.omp_clauses->lists[OMP_LIST_REDUCTION];
  3447. /* FIXME: This is currently being discussed. */
  3448. if (mask & GFC_OMP_MASK_PARALLEL)
  3449. clausesa[GFC_OMP_SPLIT_PARALLEL].if_expr
  3450. = code->ext.omp_clauses->if_expr;
  3451. else
  3452. clausesa[GFC_OMP_SPLIT_TARGET].if_expr
  3453. = code->ext.omp_clauses->if_expr;
  3454. }
  3455. if ((mask & (GFC_OMP_MASK_PARALLEL | GFC_OMP_MASK_DO))
  3456. == (GFC_OMP_MASK_PARALLEL | GFC_OMP_MASK_DO))
  3457. clausesa[GFC_OMP_SPLIT_DO].nowait = true;
  3458. }
  3459. static tree
  3460. gfc_trans_omp_do_simd (gfc_code *code, stmtblock_t *pblock,
  3461. gfc_omp_clauses *clausesa, tree omp_clauses)
  3462. {
  3463. stmtblock_t block;
  3464. gfc_omp_clauses clausesa_buf[GFC_OMP_SPLIT_NUM];
  3465. tree stmt, body, omp_do_clauses = NULL_TREE;
  3466. if (pblock == NULL)
  3467. gfc_start_block (&block);
  3468. else
  3469. gfc_init_block (&block);
  3470. if (clausesa == NULL)
  3471. {
  3472. clausesa = clausesa_buf;
  3473. gfc_split_omp_clauses (code, clausesa);
  3474. }
  3475. if (flag_openmp)
  3476. omp_do_clauses
  3477. = gfc_trans_omp_clauses (&block, &clausesa[GFC_OMP_SPLIT_DO], code->loc);
  3478. body = gfc_trans_omp_do (code, EXEC_OMP_SIMD, pblock ? pblock : &block,
  3479. &clausesa[GFC_OMP_SPLIT_SIMD], omp_clauses);
  3480. if (pblock == NULL)
  3481. {
  3482. if (TREE_CODE (body) != BIND_EXPR)
  3483. body = build3_v (BIND_EXPR, NULL, body, poplevel (1, 0));
  3484. else
  3485. poplevel (0, 0);
  3486. }
  3487. else if (TREE_CODE (body) != BIND_EXPR)
  3488. body = build3_v (BIND_EXPR, NULL, body, NULL_TREE);
  3489. if (flag_openmp)
  3490. {
  3491. stmt = make_node (OMP_FOR);
  3492. TREE_TYPE (stmt) = void_type_node;
  3493. OMP_FOR_BODY (stmt) = body;
  3494. OMP_FOR_CLAUSES (stmt) = omp_do_clauses;
  3495. }
  3496. else
  3497. stmt = body;
  3498. gfc_add_expr_to_block (&block, stmt);
  3499. return gfc_finish_block (&block);
  3500. }
  3501. static tree
  3502. gfc_trans_omp_parallel_do (gfc_code *code, stmtblock_t *pblock,
  3503. gfc_omp_clauses *clausesa)
  3504. {
  3505. stmtblock_t block, *new_pblock = pblock;
  3506. gfc_omp_clauses clausesa_buf[GFC_OMP_SPLIT_NUM];
  3507. tree stmt, omp_clauses = NULL_TREE;
  3508. if (pblock == NULL)
  3509. gfc_start_block (&block);
  3510. else
  3511. gfc_init_block (&block);
  3512. if (clausesa == NULL)
  3513. {
  3514. clausesa = clausesa_buf;
  3515. gfc_split_omp_clauses (code, clausesa);
  3516. }
  3517. omp_clauses
  3518. = gfc_trans_omp_clauses (&block, &clausesa[GFC_OMP_SPLIT_PARALLEL],
  3519. code->loc);
  3520. if (pblock == NULL)
  3521. {
  3522. if (!clausesa[GFC_OMP_SPLIT_DO].ordered
  3523. && clausesa[GFC_OMP_SPLIT_DO].sched_kind != OMP_SCHED_STATIC)
  3524. new_pblock = &block;
  3525. else
  3526. pushlevel ();
  3527. }
  3528. stmt = gfc_trans_omp_do (code, EXEC_OMP_DO, new_pblock,
  3529. &clausesa[GFC_OMP_SPLIT_DO], omp_clauses);
  3530. if (pblock == NULL)
  3531. {
  3532. if (TREE_CODE (stmt) != BIND_EXPR)
  3533. stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0));
  3534. else
  3535. poplevel (0, 0);
  3536. }
  3537. else if (TREE_CODE (stmt) != BIND_EXPR)
  3538. stmt = build3_v (BIND_EXPR, NULL, stmt, NULL_TREE);
  3539. stmt = build2_loc (input_location, OMP_PARALLEL, void_type_node, stmt,
  3540. omp_clauses);
  3541. OMP_PARALLEL_COMBINED (stmt) = 1;
  3542. gfc_add_expr_to_block (&block, stmt);
  3543. return gfc_finish_block (&block);
  3544. }
  3545. static tree
  3546. gfc_trans_omp_parallel_do_simd (gfc_code *code, stmtblock_t *pblock,
  3547. gfc_omp_clauses *clausesa)
  3548. {
  3549. stmtblock_t block;
  3550. gfc_omp_clauses clausesa_buf[GFC_OMP_SPLIT_NUM];
  3551. tree stmt, omp_clauses = NULL_TREE;
  3552. if (pblock == NULL)
  3553. gfc_start_block (&block);
  3554. else
  3555. gfc_init_block (&block);
  3556. if (clausesa == NULL)
  3557. {
  3558. clausesa = clausesa_buf;
  3559. gfc_split_omp_clauses (code, clausesa);
  3560. }
  3561. if (flag_openmp)
  3562. omp_clauses
  3563. = gfc_trans_omp_clauses (&block, &clausesa[GFC_OMP_SPLIT_PARALLEL],
  3564. code->loc);
  3565. if (pblock == NULL)
  3566. pushlevel ();
  3567. stmt = gfc_trans_omp_do_simd (code, pblock, clausesa, omp_clauses);
  3568. if (pblock == NULL)
  3569. {
  3570. if (TREE_CODE (stmt) != BIND_EXPR)
  3571. stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0));
  3572. else
  3573. poplevel (0, 0);
  3574. }
  3575. else if (TREE_CODE (stmt) != BIND_EXPR)
  3576. stmt = build3_v (BIND_EXPR, NULL, stmt, NULL_TREE);
  3577. if (flag_openmp)
  3578. {
  3579. stmt = build2_loc (input_location, OMP_PARALLEL, void_type_node, stmt,
  3580. omp_clauses);
  3581. OMP_PARALLEL_COMBINED (stmt) = 1;
  3582. }
  3583. gfc_add_expr_to_block (&block, stmt);
  3584. return gfc_finish_block (&block);
  3585. }
  3586. static tree
  3587. gfc_trans_omp_parallel_sections (gfc_code *code)
  3588. {
  3589. stmtblock_t block;
  3590. gfc_omp_clauses section_clauses;
  3591. tree stmt, omp_clauses;
  3592. memset (&section_clauses, 0, sizeof (section_clauses));
  3593. section_clauses.nowait = true;
  3594. gfc_start_block (&block);
  3595. omp_clauses = gfc_trans_omp_clauses (&block, code->ext.omp_clauses,
  3596. code->loc);
  3597. pushlevel ();
  3598. stmt = gfc_trans_omp_sections (code, &section_clauses);
  3599. if (TREE_CODE (stmt) != BIND_EXPR)
  3600. stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0));
  3601. else
  3602. poplevel (0, 0);
  3603. stmt = build2_loc (input_location, OMP_PARALLEL, void_type_node, stmt,
  3604. omp_clauses);
  3605. OMP_PARALLEL_COMBINED (stmt) = 1;
  3606. gfc_add_expr_to_block (&block, stmt);
  3607. return gfc_finish_block (&block);
  3608. }
  3609. static tree
  3610. gfc_trans_omp_parallel_workshare (gfc_code *code)
  3611. {
  3612. stmtblock_t block;
  3613. gfc_omp_clauses workshare_clauses;
  3614. tree stmt, omp_clauses;
  3615. memset (&workshare_clauses, 0, sizeof (workshare_clauses));
  3616. workshare_clauses.nowait = true;
  3617. gfc_start_block (&block);
  3618. omp_clauses = gfc_trans_omp_clauses (&block, code->ext.omp_clauses,
  3619. code->loc);
  3620. pushlevel ();
  3621. stmt = gfc_trans_omp_workshare (code, &workshare_clauses);
  3622. if (TREE_CODE (stmt) != BIND_EXPR)
  3623. stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0));
  3624. else
  3625. poplevel (0, 0);
  3626. stmt = build2_loc (input_location, OMP_PARALLEL, void_type_node, stmt,
  3627. omp_clauses);
  3628. OMP_PARALLEL_COMBINED (stmt) = 1;
  3629. gfc_add_expr_to_block (&block, stmt);
  3630. return gfc_finish_block (&block);
  3631. }
  3632. static tree
  3633. gfc_trans_omp_sections (gfc_code *code, gfc_omp_clauses *clauses)
  3634. {
  3635. stmtblock_t block, body;
  3636. tree omp_clauses, stmt;
  3637. bool has_lastprivate = clauses->lists[OMP_LIST_LASTPRIVATE] != NULL;
  3638. gfc_start_block (&block);
  3639. omp_clauses = gfc_trans_omp_clauses (&block, clauses, code->loc);
  3640. gfc_init_block (&body);
  3641. for (code = code->block; code; code = code->block)
  3642. {
  3643. /* Last section is special because of lastprivate, so even if it
  3644. is empty, chain it in. */
  3645. stmt = gfc_trans_omp_code (code->next,
  3646. has_lastprivate && code->block == NULL);
  3647. if (! IS_EMPTY_STMT (stmt))
  3648. {
  3649. stmt = build1_v (OMP_SECTION, stmt);
  3650. gfc_add_expr_to_block (&body, stmt);
  3651. }
  3652. }
  3653. stmt = gfc_finish_block (&body);
  3654. stmt = build2_loc (input_location, OMP_SECTIONS, void_type_node, stmt,
  3655. omp_clauses);
  3656. gfc_add_expr_to_block (&block, stmt);
  3657. return gfc_finish_block (&block);
  3658. }
  3659. static tree
  3660. gfc_trans_omp_single (gfc_code *code, gfc_omp_clauses *clauses)
  3661. {
  3662. tree omp_clauses = gfc_trans_omp_clauses (NULL, clauses, code->loc);
  3663. tree stmt = gfc_trans_omp_code (code->block->next, true);
  3664. stmt = build2_loc (input_location, OMP_SINGLE, void_type_node, stmt,
  3665. omp_clauses);
  3666. return stmt;
  3667. }
  3668. static tree
  3669. gfc_trans_omp_task (gfc_code *code)
  3670. {
  3671. stmtblock_t block;
  3672. tree stmt, omp_clauses;
  3673. gfc_start_block (&block);
  3674. omp_clauses = gfc_trans_omp_clauses (&block, code->ext.omp_clauses,
  3675. code->loc);
  3676. stmt = gfc_trans_omp_code (code->block->next, true);
  3677. stmt = build2_loc (input_location, OMP_TASK, void_type_node, stmt,
  3678. omp_clauses);
  3679. gfc_add_expr_to_block (&block, stmt);
  3680. return gfc_finish_block (&block);
  3681. }
  3682. static tree
  3683. gfc_trans_omp_taskgroup (gfc_code *code)
  3684. {
  3685. tree stmt = gfc_trans_code (code->block->next);
  3686. return build1_loc (input_location, OMP_TASKGROUP, void_type_node, stmt);
  3687. }
  3688. static tree
  3689. gfc_trans_omp_taskwait (void)
  3690. {
  3691. tree decl = builtin_decl_explicit (BUILT_IN_GOMP_TASKWAIT);
  3692. return build_call_expr_loc (input_location, decl, 0);
  3693. }
  3694. static tree
  3695. gfc_trans_omp_taskyield (void)
  3696. {
  3697. tree decl = builtin_decl_explicit (BUILT_IN_GOMP_TASKYIELD);
  3698. return build_call_expr_loc (input_location, decl, 0);
  3699. }
  3700. static tree
  3701. gfc_trans_omp_distribute (gfc_code *code, gfc_omp_clauses *clausesa)
  3702. {
  3703. stmtblock_t block;
  3704. gfc_omp_clauses clausesa_buf[GFC_OMP_SPLIT_NUM];
  3705. tree stmt, omp_clauses = NULL_TREE;
  3706. gfc_start_block (&block);
  3707. if (clausesa == NULL)
  3708. {
  3709. clausesa = clausesa_buf;
  3710. gfc_split_omp_clauses (code, clausesa);
  3711. }
  3712. if (flag_openmp)
  3713. omp_clauses
  3714. = gfc_trans_omp_clauses (&block, &clausesa[GFC_OMP_SPLIT_DISTRIBUTE],
  3715. code->loc);
  3716. switch (code->op)
  3717. {
  3718. case EXEC_OMP_DISTRIBUTE:
  3719. case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE:
  3720. case EXEC_OMP_TEAMS_DISTRIBUTE:
  3721. /* This is handled in gfc_trans_omp_do. */
  3722. gcc_unreachable ();
  3723. break;
  3724. case EXEC_OMP_DISTRIBUTE_PARALLEL_DO:
  3725. case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO:
  3726. case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO:
  3727. stmt = gfc_trans_omp_parallel_do (code, &block, clausesa);
  3728. if (TREE_CODE (stmt) != BIND_EXPR)
  3729. stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0));
  3730. else
  3731. poplevel (0, 0);
  3732. break;
  3733. case EXEC_OMP_DISTRIBUTE_PARALLEL_DO_SIMD:
  3734. case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
  3735. case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
  3736. stmt = gfc_trans_omp_parallel_do_simd (code, &block, clausesa);
  3737. if (TREE_CODE (stmt) != BIND_EXPR)
  3738. stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0));
  3739. else
  3740. poplevel (0, 0);
  3741. break;
  3742. case EXEC_OMP_DISTRIBUTE_SIMD:
  3743. case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD:
  3744. case EXEC_OMP_TEAMS_DISTRIBUTE_SIMD:
  3745. stmt = gfc_trans_omp_do (code, EXEC_OMP_SIMD, &block,
  3746. &clausesa[GFC_OMP_SPLIT_SIMD], NULL_TREE);
  3747. if (TREE_CODE (stmt) != BIND_EXPR)
  3748. stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0));
  3749. else
  3750. poplevel (0, 0);
  3751. break;
  3752. default:
  3753. gcc_unreachable ();
  3754. }
  3755. if (flag_openmp)
  3756. {
  3757. tree distribute = make_node (OMP_DISTRIBUTE);
  3758. TREE_TYPE (distribute) = void_type_node;
  3759. OMP_FOR_BODY (distribute) = stmt;
  3760. OMP_FOR_CLAUSES (distribute) = omp_clauses;
  3761. stmt = distribute;
  3762. }
  3763. gfc_add_expr_to_block (&block, stmt);
  3764. return gfc_finish_block (&block);
  3765. }
  3766. static tree
  3767. gfc_trans_omp_teams (gfc_code *code, gfc_omp_clauses *clausesa)
  3768. {
  3769. stmtblock_t block;
  3770. gfc_omp_clauses clausesa_buf[GFC_OMP_SPLIT_NUM];
  3771. tree stmt, omp_clauses = NULL_TREE;
  3772. bool combined = true;
  3773. gfc_start_block (&block);
  3774. if (clausesa == NULL)
  3775. {
  3776. clausesa = clausesa_buf;
  3777. gfc_split_omp_clauses (code, clausesa);
  3778. }
  3779. if (flag_openmp)
  3780. omp_clauses
  3781. = gfc_trans_omp_clauses (&block, &clausesa[GFC_OMP_SPLIT_TEAMS],
  3782. code->loc);
  3783. switch (code->op)
  3784. {
  3785. case EXEC_OMP_TARGET_TEAMS:
  3786. case EXEC_OMP_TEAMS:
  3787. stmt = gfc_trans_omp_code (code->block->next, true);
  3788. combined = false;
  3789. break;
  3790. case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE:
  3791. case EXEC_OMP_TEAMS_DISTRIBUTE:
  3792. stmt = gfc_trans_omp_do (code, EXEC_OMP_DISTRIBUTE, NULL,
  3793. &clausesa[GFC_OMP_SPLIT_DISTRIBUTE],
  3794. NULL);
  3795. break;
  3796. default:
  3797. stmt = gfc_trans_omp_distribute (code, clausesa);
  3798. break;
  3799. }
  3800. stmt = build2_loc (input_location, OMP_TEAMS, void_type_node, stmt,
  3801. omp_clauses);
  3802. if (combined)
  3803. OMP_TEAMS_COMBINED (stmt) = 1;
  3804. gfc_add_expr_to_block (&block, stmt);
  3805. return gfc_finish_block (&block);
  3806. }
  3807. static tree
  3808. gfc_trans_omp_target (gfc_code *code)
  3809. {
  3810. stmtblock_t block;
  3811. gfc_omp_clauses clausesa[GFC_OMP_SPLIT_NUM];
  3812. tree stmt, omp_clauses = NULL_TREE;
  3813. gfc_start_block (&block);
  3814. gfc_split_omp_clauses (code, clausesa);
  3815. if (flag_openmp)
  3816. omp_clauses
  3817. = gfc_trans_omp_clauses (&block, &clausesa[GFC_OMP_SPLIT_TARGET],
  3818. code->loc);
  3819. if (code->op == EXEC_OMP_TARGET)
  3820. stmt = gfc_trans_omp_code (code->block->next, true);
  3821. else
  3822. {
  3823. pushlevel ();
  3824. stmt = gfc_trans_omp_teams (code, clausesa);
  3825. if (TREE_CODE (stmt) != BIND_EXPR)
  3826. stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0));
  3827. else
  3828. poplevel (0, 0);
  3829. }
  3830. if (flag_openmp)
  3831. stmt = build2_loc (input_location, OMP_TARGET, void_type_node, stmt,
  3832. omp_clauses);
  3833. gfc_add_expr_to_block (&block, stmt);
  3834. return gfc_finish_block (&block);
  3835. }
  3836. static tree
  3837. gfc_trans_omp_target_data (gfc_code *code)
  3838. {
  3839. stmtblock_t block;
  3840. tree stmt, omp_clauses;
  3841. gfc_start_block (&block);
  3842. omp_clauses = gfc_trans_omp_clauses (&block, code->ext.omp_clauses,
  3843. code->loc);
  3844. stmt = gfc_trans_omp_code (code->block->next, true);
  3845. stmt = build2_loc (input_location, OMP_TARGET_DATA, void_type_node, stmt,
  3846. omp_clauses);
  3847. gfc_add_expr_to_block (&block, stmt);
  3848. return gfc_finish_block (&block);
  3849. }
  3850. static tree
  3851. gfc_trans_omp_target_update (gfc_code *code)
  3852. {
  3853. stmtblock_t block;
  3854. tree stmt, omp_clauses;
  3855. gfc_start_block (&block);
  3856. omp_clauses = gfc_trans_omp_clauses (&block, code->ext.omp_clauses,
  3857. code->loc);
  3858. stmt = build1_loc (input_location, OMP_TARGET_UPDATE, void_type_node,
  3859. omp_clauses);
  3860. gfc_add_expr_to_block (&block, stmt);
  3861. return gfc_finish_block (&block);
  3862. }
  3863. static tree
  3864. gfc_trans_omp_workshare (gfc_code *code, gfc_omp_clauses *clauses)
  3865. {
  3866. tree res, tmp, stmt;
  3867. stmtblock_t block, *pblock = NULL;
  3868. stmtblock_t singleblock;
  3869. int saved_ompws_flags;
  3870. bool singleblock_in_progress = false;
  3871. /* True if previous gfc_code in workshare construct is not workshared. */
  3872. bool prev_singleunit;
  3873. code = code->block->next;
  3874. pushlevel ();
  3875. gfc_start_block (&block);
  3876. pblock = &block;
  3877. ompws_flags = OMPWS_WORKSHARE_FLAG;
  3878. prev_singleunit = false;
  3879. /* Translate statements one by one to trees until we reach
  3880. the end of the workshare construct. Adjacent gfc_codes that
  3881. are a single unit of work are clustered and encapsulated in a
  3882. single OMP_SINGLE construct. */
  3883. for (; code; code = code->next)
  3884. {
  3885. if (code->here != 0)
  3886. {
  3887. res = gfc_trans_label_here (code);
  3888. gfc_add_expr_to_block (pblock, res);
  3889. }
  3890. /* No dependence analysis, use for clauses with wait.
  3891. If this is the last gfc_code, use default omp_clauses. */
  3892. if (code->next == NULL && clauses->nowait)
  3893. ompws_flags |= OMPWS_NOWAIT;
  3894. /* By default, every gfc_code is a single unit of work. */
  3895. ompws_flags |= OMPWS_CURR_SINGLEUNIT;
  3896. ompws_flags &= ~OMPWS_SCALARIZER_WS;
  3897. switch (code->op)
  3898. {
  3899. case EXEC_NOP:
  3900. res = NULL_TREE;
  3901. break;
  3902. case EXEC_ASSIGN:
  3903. res = gfc_trans_assign (code);
  3904. break;
  3905. case EXEC_POINTER_ASSIGN:
  3906. res = gfc_trans_pointer_assign (code);
  3907. break;
  3908. case EXEC_INIT_ASSIGN:
  3909. res = gfc_trans_init_assign (code);
  3910. break;
  3911. case EXEC_FORALL:
  3912. res = gfc_trans_forall (code);
  3913. break;
  3914. case EXEC_WHERE:
  3915. res = gfc_trans_where (code);
  3916. break;
  3917. case EXEC_OMP_ATOMIC:
  3918. res = gfc_trans_omp_directive (code);
  3919. break;
  3920. case EXEC_OMP_PARALLEL:
  3921. case EXEC_OMP_PARALLEL_DO:
  3922. case EXEC_OMP_PARALLEL_SECTIONS:
  3923. case EXEC_OMP_PARALLEL_WORKSHARE:
  3924. case EXEC_OMP_CRITICAL:
  3925. saved_ompws_flags = ompws_flags;
  3926. ompws_flags = 0;
  3927. res = gfc_trans_omp_directive (code);
  3928. ompws_flags = saved_ompws_flags;
  3929. break;
  3930. default:
  3931. gfc_internal_error ("gfc_trans_omp_workshare(): Bad statement code");
  3932. }
  3933. gfc_set_backend_locus (&code->loc);
  3934. if (res != NULL_TREE && ! IS_EMPTY_STMT (res))
  3935. {
  3936. if (prev_singleunit)
  3937. {
  3938. if (ompws_flags & OMPWS_CURR_SINGLEUNIT)
  3939. /* Add current gfc_code to single block. */
  3940. gfc_add_expr_to_block (&singleblock, res);
  3941. else
  3942. {
  3943. /* Finish single block and add it to pblock. */
  3944. tmp = gfc_finish_block (&singleblock);
  3945. tmp = build2_loc (input_location, OMP_SINGLE,
  3946. void_type_node, tmp, NULL_TREE);
  3947. gfc_add_expr_to_block (pblock, tmp);
  3948. /* Add current gfc_code to pblock. */
  3949. gfc_add_expr_to_block (pblock, res);
  3950. singleblock_in_progress = false;
  3951. }
  3952. }
  3953. else
  3954. {
  3955. if (ompws_flags & OMPWS_CURR_SINGLEUNIT)
  3956. {
  3957. /* Start single block. */
  3958. gfc_init_block (&singleblock);
  3959. gfc_add_expr_to_block (&singleblock, res);
  3960. singleblock_in_progress = true;
  3961. }
  3962. else
  3963. /* Add the new statement to the block. */
  3964. gfc_add_expr_to_block (pblock, res);
  3965. }
  3966. prev_singleunit = (ompws_flags & OMPWS_CURR_SINGLEUNIT) != 0;
  3967. }
  3968. }
  3969. /* Finish remaining SINGLE block, if we were in the middle of one. */
  3970. if (singleblock_in_progress)
  3971. {
  3972. /* Finish single block and add it to pblock. */
  3973. tmp = gfc_finish_block (&singleblock);
  3974. tmp = build2_loc (input_location, OMP_SINGLE, void_type_node, tmp,
  3975. clauses->nowait
  3976. ? build_omp_clause (input_location, OMP_CLAUSE_NOWAIT)
  3977. : NULL_TREE);
  3978. gfc_add_expr_to_block (pblock, tmp);
  3979. }
  3980. stmt = gfc_finish_block (pblock);
  3981. if (TREE_CODE (stmt) != BIND_EXPR)
  3982. {
  3983. if (!IS_EMPTY_STMT (stmt))
  3984. {
  3985. tree bindblock = poplevel (1, 0);
  3986. stmt = build3_v (BIND_EXPR, NULL, stmt, bindblock);
  3987. }
  3988. else
  3989. poplevel (0, 0);
  3990. }
  3991. else
  3992. poplevel (0, 0);
  3993. if (IS_EMPTY_STMT (stmt) && !clauses->nowait)
  3994. stmt = gfc_trans_omp_barrier ();
  3995. ompws_flags = 0;
  3996. return stmt;
  3997. }
  3998. tree
  3999. gfc_trans_oacc_declare (stmtblock_t *block, gfc_namespace *ns)
  4000. {
  4001. tree oacc_clauses;
  4002. oacc_clauses = gfc_trans_omp_clauses (block, ns->oacc_declare_clauses,
  4003. ns->oacc_declare_clauses->loc);
  4004. return build1_loc (ns->oacc_declare_clauses->loc.lb->location,
  4005. OACC_DECLARE, void_type_node, oacc_clauses);
  4006. }
  4007. tree
  4008. gfc_trans_oacc_directive (gfc_code *code)
  4009. {
  4010. switch (code->op)
  4011. {
  4012. case EXEC_OACC_PARALLEL_LOOP:
  4013. case EXEC_OACC_KERNELS_LOOP:
  4014. return gfc_trans_oacc_combined_directive (code);
  4015. case EXEC_OACC_PARALLEL:
  4016. case EXEC_OACC_KERNELS:
  4017. case EXEC_OACC_DATA:
  4018. case EXEC_OACC_HOST_DATA:
  4019. return gfc_trans_oacc_construct (code);
  4020. case EXEC_OACC_LOOP:
  4021. return gfc_trans_omp_do (code, code->op, NULL, code->ext.omp_clauses,
  4022. NULL);
  4023. case EXEC_OACC_UPDATE:
  4024. case EXEC_OACC_CACHE:
  4025. case EXEC_OACC_ENTER_DATA:
  4026. case EXEC_OACC_EXIT_DATA:
  4027. return gfc_trans_oacc_executable_directive (code);
  4028. case EXEC_OACC_WAIT:
  4029. return gfc_trans_oacc_wait_directive (code);
  4030. default:
  4031. gcc_unreachable ();
  4032. }
  4033. }
  4034. tree
  4035. gfc_trans_omp_directive (gfc_code *code)
  4036. {
  4037. switch (code->op)
  4038. {
  4039. case EXEC_OMP_ATOMIC:
  4040. return gfc_trans_omp_atomic (code);
  4041. case EXEC_OMP_BARRIER:
  4042. return gfc_trans_omp_barrier ();
  4043. case EXEC_OMP_CANCEL:
  4044. return gfc_trans_omp_cancel (code);
  4045. case EXEC_OMP_CANCELLATION_POINT:
  4046. return gfc_trans_omp_cancellation_point (code);
  4047. case EXEC_OMP_CRITICAL:
  4048. return gfc_trans_omp_critical (code);
  4049. case EXEC_OMP_DISTRIBUTE:
  4050. case EXEC_OMP_DO:
  4051. case EXEC_OMP_SIMD:
  4052. return gfc_trans_omp_do (code, code->op, NULL, code->ext.omp_clauses,
  4053. NULL);
  4054. case EXEC_OMP_DISTRIBUTE_PARALLEL_DO:
  4055. case EXEC_OMP_DISTRIBUTE_PARALLEL_DO_SIMD:
  4056. case EXEC_OMP_DISTRIBUTE_SIMD:
  4057. return gfc_trans_omp_distribute (code, NULL);
  4058. case EXEC_OMP_DO_SIMD:
  4059. return gfc_trans_omp_do_simd (code, NULL, NULL, NULL_TREE);
  4060. case EXEC_OMP_FLUSH:
  4061. return gfc_trans_omp_flush ();
  4062. case EXEC_OMP_MASTER:
  4063. return gfc_trans_omp_master (code);
  4064. case EXEC_OMP_ORDERED:
  4065. return gfc_trans_omp_ordered (code);
  4066. case EXEC_OMP_PARALLEL:
  4067. return gfc_trans_omp_parallel (code);
  4068. case EXEC_OMP_PARALLEL_DO:
  4069. return gfc_trans_omp_parallel_do (code, NULL, NULL);
  4070. case EXEC_OMP_PARALLEL_DO_SIMD:
  4071. return gfc_trans_omp_parallel_do_simd (code, NULL, NULL);
  4072. case EXEC_OMP_PARALLEL_SECTIONS:
  4073. return gfc_trans_omp_parallel_sections (code);
  4074. case EXEC_OMP_PARALLEL_WORKSHARE:
  4075. return gfc_trans_omp_parallel_workshare (code);
  4076. case EXEC_OMP_SECTIONS:
  4077. return gfc_trans_omp_sections (code, code->ext.omp_clauses);
  4078. case EXEC_OMP_SINGLE:
  4079. return gfc_trans_omp_single (code, code->ext.omp_clauses);
  4080. case EXEC_OMP_TARGET:
  4081. case EXEC_OMP_TARGET_TEAMS:
  4082. case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE:
  4083. case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO:
  4084. case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
  4085. case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD:
  4086. return gfc_trans_omp_target (code);
  4087. case EXEC_OMP_TARGET_DATA:
  4088. return gfc_trans_omp_target_data (code);
  4089. case EXEC_OMP_TARGET_UPDATE:
  4090. return gfc_trans_omp_target_update (code);
  4091. case EXEC_OMP_TASK:
  4092. return gfc_trans_omp_task (code);
  4093. case EXEC_OMP_TASKGROUP:
  4094. return gfc_trans_omp_taskgroup (code);
  4095. case EXEC_OMP_TASKWAIT:
  4096. return gfc_trans_omp_taskwait ();
  4097. case EXEC_OMP_TASKYIELD:
  4098. return gfc_trans_omp_taskyield ();
  4099. case EXEC_OMP_TEAMS:
  4100. case EXEC_OMP_TEAMS_DISTRIBUTE:
  4101. case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO:
  4102. case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
  4103. case EXEC_OMP_TEAMS_DISTRIBUTE_SIMD:
  4104. return gfc_trans_omp_teams (code, NULL);
  4105. case EXEC_OMP_WORKSHARE:
  4106. return gfc_trans_omp_workshare (code, code->ext.omp_clauses);
  4107. default:
  4108. gcc_unreachable ();
  4109. }
  4110. }
  4111. void
  4112. gfc_trans_omp_declare_simd (gfc_namespace *ns)
  4113. {
  4114. if (ns->entries)
  4115. return;
  4116. gfc_omp_declare_simd *ods;
  4117. for (ods = ns->omp_declare_simd; ods; ods = ods->next)
  4118. {
  4119. tree c = gfc_trans_omp_clauses (NULL, ods->clauses, ods->where, true);
  4120. tree fndecl = ns->proc_name->backend_decl;
  4121. if (c != NULL_TREE)
  4122. c = tree_cons (NULL_TREE, c, NULL_TREE);
  4123. c = build_tree_list (get_identifier ("omp declare simd"), c);
  4124. TREE_CHAIN (c) = DECL_ATTRIBUTES (fndecl);
  4125. DECL_ATTRIBUTES (fndecl) = c;
  4126. }
  4127. }