isl_coalesce.c 130 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262
  1. /*
  2. * Copyright 2008-2009 Katholieke Universiteit Leuven
  3. * Copyright 2010 INRIA Saclay
  4. * Copyright 2012-2013 Ecole Normale Superieure
  5. * Copyright 2014 INRIA Rocquencourt
  6. * Copyright 2016 INRIA Paris
  7. * Copyright 2020 Cerebras Systems
  8. *
  9. * Use of this software is governed by the MIT license
  10. *
  11. * Written by Sven Verdoolaege, K.U.Leuven, Departement
  12. * Computerwetenschappen, Celestijnenlaan 200A, B-3001 Leuven, Belgium
  13. * and INRIA Saclay - Ile-de-France, Parc Club Orsay Universite,
  14. * ZAC des vignes, 4 rue Jacques Monod, 91893 Orsay, France
  15. * and Ecole Normale Superieure, 45 rue d’Ulm, 75230 Paris, France
  16. * and Inria Paris - Rocquencourt, Domaine de Voluceau - Rocquencourt,
  17. * B.P. 105 - 78153 Le Chesnay, France
  18. * and Centre de Recherche Inria de Paris, 2 rue Simone Iff - Voie DQ12,
  19. * CS 42112, 75589 Paris Cedex 12, France
  20. * and Cerebras Systems, 175 S San Antonio Rd, Los Altos, CA, USA
  21. */
  22. #include <isl_ctx_private.h>
  23. #include "isl_map_private.h"
  24. #include <isl_seq.h>
  25. #include <isl/options.h>
  26. #include "isl_tab.h"
  27. #include <isl_mat_private.h>
  28. #include <isl_local_space_private.h>
  29. #include <isl_val_private.h>
  30. #include <isl_vec_private.h>
  31. #include <isl_aff_private.h>
  32. #include <isl_equalities.h>
  33. #include <isl_constraint_private.h>
  34. #include <set_to_map.c>
  35. #include <set_from_map.c>
  36. #define STATUS_ERROR -1
  37. #define STATUS_REDUNDANT 1
  38. #define STATUS_VALID 2
  39. #define STATUS_SEPARATE 3
  40. #define STATUS_CUT 4
  41. #define STATUS_ADJ_EQ 5
  42. #define STATUS_ADJ_INEQ 6
  43. static int status_in(isl_int *ineq, struct isl_tab *tab)
  44. {
  45. enum isl_ineq_type type = isl_tab_ineq_type(tab, ineq);
  46. switch (type) {
  47. default:
  48. case isl_ineq_error: return STATUS_ERROR;
  49. case isl_ineq_redundant: return STATUS_VALID;
  50. case isl_ineq_separate: return STATUS_SEPARATE;
  51. case isl_ineq_cut: return STATUS_CUT;
  52. case isl_ineq_adj_eq: return STATUS_ADJ_EQ;
  53. case isl_ineq_adj_ineq: return STATUS_ADJ_INEQ;
  54. }
  55. }
  56. /* Compute the position of the equalities of basic map "bmap_i"
  57. * with respect to the basic map represented by "tab_j".
  58. * The resulting array has twice as many entries as the number
  59. * of equalities corresponding to the two inequalities to which
  60. * each equality corresponds.
  61. */
  62. static int *eq_status_in(__isl_keep isl_basic_map *bmap_i,
  63. struct isl_tab *tab_j)
  64. {
  65. int k, l;
  66. int *eq;
  67. isl_size dim;
  68. dim = isl_basic_map_dim(bmap_i, isl_dim_all);
  69. if (dim < 0)
  70. return NULL;
  71. eq = isl_calloc_array(bmap_i->ctx, int, 2 * bmap_i->n_eq);
  72. if (!eq)
  73. return NULL;
  74. for (k = 0; k < bmap_i->n_eq; ++k) {
  75. for (l = 0; l < 2; ++l) {
  76. isl_seq_neg(bmap_i->eq[k], bmap_i->eq[k], 1+dim);
  77. eq[2 * k + l] = status_in(bmap_i->eq[k], tab_j);
  78. if (eq[2 * k + l] == STATUS_ERROR)
  79. goto error;
  80. }
  81. }
  82. return eq;
  83. error:
  84. free(eq);
  85. return NULL;
  86. }
  87. /* Compute the position of the inequalities of basic map "bmap_i"
  88. * (also represented by "tab_i", if not NULL) with respect to the basic map
  89. * represented by "tab_j".
  90. */
  91. static int *ineq_status_in(__isl_keep isl_basic_map *bmap_i,
  92. struct isl_tab *tab_i, struct isl_tab *tab_j)
  93. {
  94. int k;
  95. unsigned n_eq = bmap_i->n_eq;
  96. int *ineq = isl_calloc_array(bmap_i->ctx, int, bmap_i->n_ineq);
  97. if (!ineq)
  98. return NULL;
  99. for (k = 0; k < bmap_i->n_ineq; ++k) {
  100. if (tab_i && isl_tab_is_redundant(tab_i, n_eq + k)) {
  101. ineq[k] = STATUS_REDUNDANT;
  102. continue;
  103. }
  104. ineq[k] = status_in(bmap_i->ineq[k], tab_j);
  105. if (ineq[k] == STATUS_ERROR)
  106. goto error;
  107. if (ineq[k] == STATUS_SEPARATE)
  108. break;
  109. }
  110. return ineq;
  111. error:
  112. free(ineq);
  113. return NULL;
  114. }
  115. static int any(int *con, unsigned len, int status)
  116. {
  117. int i;
  118. for (i = 0; i < len ; ++i)
  119. if (con[i] == status)
  120. return 1;
  121. return 0;
  122. }
  123. /* Return the first position of "status" in the list "con" of length "len".
  124. * Return -1 if there is no such entry.
  125. */
  126. static int find(int *con, unsigned len, int status)
  127. {
  128. int i;
  129. for (i = 0; i < len ; ++i)
  130. if (con[i] == status)
  131. return i;
  132. return -1;
  133. }
  134. static int count(int *con, unsigned len, int status)
  135. {
  136. int i;
  137. int c = 0;
  138. for (i = 0; i < len ; ++i)
  139. if (con[i] == status)
  140. c++;
  141. return c;
  142. }
  143. static int all(int *con, unsigned len, int status)
  144. {
  145. int i;
  146. for (i = 0; i < len ; ++i) {
  147. if (con[i] == STATUS_REDUNDANT)
  148. continue;
  149. if (con[i] != status)
  150. return 0;
  151. }
  152. return 1;
  153. }
  154. /* Internal information associated to a basic map in a map
  155. * that is to be coalesced by isl_map_coalesce.
  156. *
  157. * "bmap" is the basic map itself (or NULL if "removed" is set)
  158. * "tab" is the corresponding tableau (or NULL if "removed" is set)
  159. * "hull_hash" identifies the affine space in which "bmap" lives.
  160. * "modified" is set if this basic map may not be identical
  161. * to any of the basic maps in the input.
  162. * "removed" is set if this basic map has been removed from the map
  163. * "simplify" is set if this basic map may have some unknown integer
  164. * divisions that were not present in the input basic maps. The basic
  165. * map should then be simplified such that we may be able to find
  166. * a definition among the constraints.
  167. *
  168. * "eq" and "ineq" are only set if we are currently trying to coalesce
  169. * this basic map with another basic map, in which case they represent
  170. * the position of the inequalities of this basic map with respect to
  171. * the other basic map. The number of elements in the "eq" array
  172. * is twice the number of equalities in the "bmap", corresponding
  173. * to the two inequalities that make up each equality.
  174. */
  175. struct isl_coalesce_info {
  176. isl_basic_map *bmap;
  177. struct isl_tab *tab;
  178. uint32_t hull_hash;
  179. int modified;
  180. int removed;
  181. int simplify;
  182. int *eq;
  183. int *ineq;
  184. };
  185. /* Is there any (half of an) equality constraint in the description
  186. * of the basic map represented by "info" that
  187. * has position "status" with respect to the other basic map?
  188. */
  189. static int any_eq(struct isl_coalesce_info *info, int status)
  190. {
  191. isl_size n_eq;
  192. n_eq = isl_basic_map_n_equality(info->bmap);
  193. return any(info->eq, 2 * n_eq, status);
  194. }
  195. /* Is there any inequality constraint in the description
  196. * of the basic map represented by "info" that
  197. * has position "status" with respect to the other basic map?
  198. */
  199. static int any_ineq(struct isl_coalesce_info *info, int status)
  200. {
  201. isl_size n_ineq;
  202. n_ineq = isl_basic_map_n_inequality(info->bmap);
  203. return any(info->ineq, n_ineq, status);
  204. }
  205. /* Return the position of the first half on an equality constraint
  206. * in the description of the basic map represented by "info" that
  207. * has position "status" with respect to the other basic map.
  208. * The returned value is twice the position of the equality constraint
  209. * plus zero for the negative half and plus one for the positive half.
  210. * Return -1 if there is no such entry.
  211. */
  212. static int find_eq(struct isl_coalesce_info *info, int status)
  213. {
  214. isl_size n_eq;
  215. n_eq = isl_basic_map_n_equality(info->bmap);
  216. return find(info->eq, 2 * n_eq, status);
  217. }
  218. /* Return the position of the first inequality constraint in the description
  219. * of the basic map represented by "info" that
  220. * has position "status" with respect to the other basic map.
  221. * Return -1 if there is no such entry.
  222. */
  223. static int find_ineq(struct isl_coalesce_info *info, int status)
  224. {
  225. isl_size n_ineq;
  226. n_ineq = isl_basic_map_n_inequality(info->bmap);
  227. return find(info->ineq, n_ineq, status);
  228. }
  229. /* Return the number of (halves of) equality constraints in the description
  230. * of the basic map represented by "info" that
  231. * have position "status" with respect to the other basic map.
  232. */
  233. static int count_eq(struct isl_coalesce_info *info, int status)
  234. {
  235. isl_size n_eq;
  236. n_eq = isl_basic_map_n_equality(info->bmap);
  237. return count(info->eq, 2 * n_eq, status);
  238. }
  239. /* Return the number of inequality constraints in the description
  240. * of the basic map represented by "info" that
  241. * have position "status" with respect to the other basic map.
  242. */
  243. static int count_ineq(struct isl_coalesce_info *info, int status)
  244. {
  245. isl_size n_ineq;
  246. n_ineq = isl_basic_map_n_inequality(info->bmap);
  247. return count(info->ineq, n_ineq, status);
  248. }
  249. /* Are all non-redundant constraints of the basic map represented by "info"
  250. * either valid or cut constraints with respect to the other basic map?
  251. */
  252. static int all_valid_or_cut(struct isl_coalesce_info *info)
  253. {
  254. int i;
  255. for (i = 0; i < 2 * info->bmap->n_eq; ++i) {
  256. if (info->eq[i] == STATUS_REDUNDANT)
  257. continue;
  258. if (info->eq[i] == STATUS_VALID)
  259. continue;
  260. if (info->eq[i] == STATUS_CUT)
  261. continue;
  262. return 0;
  263. }
  264. for (i = 0; i < info->bmap->n_ineq; ++i) {
  265. if (info->ineq[i] == STATUS_REDUNDANT)
  266. continue;
  267. if (info->ineq[i] == STATUS_VALID)
  268. continue;
  269. if (info->ineq[i] == STATUS_CUT)
  270. continue;
  271. return 0;
  272. }
  273. return 1;
  274. }
  275. /* Compute the hash of the (apparent) affine hull of info->bmap (with
  276. * the existentially quantified variables removed) and store it
  277. * in info->hash.
  278. */
  279. static int coalesce_info_set_hull_hash(struct isl_coalesce_info *info)
  280. {
  281. isl_basic_map *hull;
  282. isl_size n_div;
  283. hull = isl_basic_map_copy(info->bmap);
  284. hull = isl_basic_map_plain_affine_hull(hull);
  285. n_div = isl_basic_map_dim(hull, isl_dim_div);
  286. if (n_div < 0)
  287. hull = isl_basic_map_free(hull);
  288. hull = isl_basic_map_drop_constraints_involving_dims(hull,
  289. isl_dim_div, 0, n_div);
  290. info->hull_hash = isl_basic_map_get_hash(hull);
  291. isl_basic_map_free(hull);
  292. return hull ? 0 : -1;
  293. }
  294. /* Free all the allocated memory in an array
  295. * of "n" isl_coalesce_info elements.
  296. */
  297. static void clear_coalesce_info(int n, struct isl_coalesce_info *info)
  298. {
  299. int i;
  300. if (!info)
  301. return;
  302. for (i = 0; i < n; ++i) {
  303. isl_basic_map_free(info[i].bmap);
  304. isl_tab_free(info[i].tab);
  305. }
  306. free(info);
  307. }
  308. /* Clear the memory associated to "info".
  309. */
  310. static void clear(struct isl_coalesce_info *info)
  311. {
  312. info->bmap = isl_basic_map_free(info->bmap);
  313. isl_tab_free(info->tab);
  314. info->tab = NULL;
  315. }
  316. /* Drop the basic map represented by "info".
  317. * That is, clear the memory associated to the entry and
  318. * mark it as having been removed.
  319. */
  320. static void drop(struct isl_coalesce_info *info)
  321. {
  322. clear(info);
  323. info->removed = 1;
  324. }
  325. /* Exchange the information in "info1" with that in "info2".
  326. */
  327. static void exchange(struct isl_coalesce_info *info1,
  328. struct isl_coalesce_info *info2)
  329. {
  330. struct isl_coalesce_info info;
  331. info = *info1;
  332. *info1 = *info2;
  333. *info2 = info;
  334. }
  335. /* This type represents the kind of change that has been performed
  336. * while trying to coalesce two basic maps.
  337. *
  338. * isl_change_none: nothing was changed
  339. * isl_change_drop_first: the first basic map was removed
  340. * isl_change_drop_second: the second basic map was removed
  341. * isl_change_fuse: the two basic maps were replaced by a new basic map.
  342. */
  343. enum isl_change {
  344. isl_change_error = -1,
  345. isl_change_none = 0,
  346. isl_change_drop_first,
  347. isl_change_drop_second,
  348. isl_change_fuse,
  349. };
  350. /* Update "change" based on an interchange of the first and the second
  351. * basic map. That is, interchange isl_change_drop_first and
  352. * isl_change_drop_second.
  353. */
  354. static enum isl_change invert_change(enum isl_change change)
  355. {
  356. switch (change) {
  357. case isl_change_error:
  358. return isl_change_error;
  359. case isl_change_none:
  360. return isl_change_none;
  361. case isl_change_drop_first:
  362. return isl_change_drop_second;
  363. case isl_change_drop_second:
  364. return isl_change_drop_first;
  365. case isl_change_fuse:
  366. return isl_change_fuse;
  367. }
  368. return isl_change_error;
  369. }
  370. /* Add the valid constraints of the basic map represented by "info"
  371. * to "bmap". "len" is the size of the constraints.
  372. * If only one of the pair of inequalities that make up an equality
  373. * is valid, then add that inequality.
  374. */
  375. static __isl_give isl_basic_map *add_valid_constraints(
  376. __isl_take isl_basic_map *bmap, struct isl_coalesce_info *info,
  377. unsigned len)
  378. {
  379. int k, l;
  380. if (!bmap)
  381. return NULL;
  382. for (k = 0; k < info->bmap->n_eq; ++k) {
  383. if (info->eq[2 * k] == STATUS_VALID &&
  384. info->eq[2 * k + 1] == STATUS_VALID) {
  385. l = isl_basic_map_alloc_equality(bmap);
  386. if (l < 0)
  387. return isl_basic_map_free(bmap);
  388. isl_seq_cpy(bmap->eq[l], info->bmap->eq[k], len);
  389. } else if (info->eq[2 * k] == STATUS_VALID) {
  390. l = isl_basic_map_alloc_inequality(bmap);
  391. if (l < 0)
  392. return isl_basic_map_free(bmap);
  393. isl_seq_neg(bmap->ineq[l], info->bmap->eq[k], len);
  394. } else if (info->eq[2 * k + 1] == STATUS_VALID) {
  395. l = isl_basic_map_alloc_inequality(bmap);
  396. if (l < 0)
  397. return isl_basic_map_free(bmap);
  398. isl_seq_cpy(bmap->ineq[l], info->bmap->eq[k], len);
  399. }
  400. }
  401. for (k = 0; k < info->bmap->n_ineq; ++k) {
  402. if (info->ineq[k] != STATUS_VALID)
  403. continue;
  404. l = isl_basic_map_alloc_inequality(bmap);
  405. if (l < 0)
  406. return isl_basic_map_free(bmap);
  407. isl_seq_cpy(bmap->ineq[l], info->bmap->ineq[k], len);
  408. }
  409. return bmap;
  410. }
  411. /* Is "bmap" defined by a number of (non-redundant) constraints that
  412. * is greater than the number of constraints of basic maps i and j combined?
  413. * Equalities are counted as two inequalities.
  414. */
  415. static int number_of_constraints_increases(int i, int j,
  416. struct isl_coalesce_info *info,
  417. __isl_keep isl_basic_map *bmap, struct isl_tab *tab)
  418. {
  419. int k, n_old, n_new;
  420. n_old = 2 * info[i].bmap->n_eq + info[i].bmap->n_ineq;
  421. n_old += 2 * info[j].bmap->n_eq + info[j].bmap->n_ineq;
  422. n_new = 2 * bmap->n_eq;
  423. for (k = 0; k < bmap->n_ineq; ++k)
  424. if (!isl_tab_is_redundant(tab, bmap->n_eq + k))
  425. ++n_new;
  426. return n_new > n_old;
  427. }
  428. /* Replace the pair of basic maps i and j by the basic map bounded
  429. * by the valid constraints in both basic maps and the constraints
  430. * in extra (if not NULL).
  431. * Place the fused basic map in the position that is the smallest of i and j.
  432. *
  433. * If "detect_equalities" is set, then look for equalities encoded
  434. * as pairs of inequalities.
  435. * If "check_number" is set, then the original basic maps are only
  436. * replaced if the total number of constraints does not increase.
  437. * While the number of integer divisions in the two basic maps
  438. * is assumed to be the same, the actual definitions may be different.
  439. * We only copy the definition from one of the basic maps if it is
  440. * the same as that of the other basic map. Otherwise, we mark
  441. * the integer division as unknown and simplify the basic map
  442. * in an attempt to recover the integer division definition.
  443. * If any extra constraints get introduced, then these may
  444. * involve integer divisions with a unit coefficient.
  445. * Eliminate those that do not appear with any other coefficient
  446. * in other constraints, to ensure they get eliminated completely,
  447. * improving the chances of further coalescing.
  448. */
  449. static enum isl_change fuse(int i, int j, struct isl_coalesce_info *info,
  450. __isl_keep isl_mat *extra, int detect_equalities, int check_number)
  451. {
  452. int k, l;
  453. struct isl_basic_map *fused = NULL;
  454. struct isl_tab *fused_tab = NULL;
  455. isl_size total = isl_basic_map_dim(info[i].bmap, isl_dim_all);
  456. unsigned extra_rows = extra ? extra->n_row : 0;
  457. unsigned n_eq, n_ineq;
  458. int simplify = 0;
  459. if (total < 0)
  460. return isl_change_error;
  461. if (j < i)
  462. return fuse(j, i, info, extra, detect_equalities, check_number);
  463. n_eq = info[i].bmap->n_eq + info[j].bmap->n_eq;
  464. n_ineq = info[i].bmap->n_ineq + info[j].bmap->n_ineq;
  465. fused = isl_basic_map_alloc_space(isl_space_copy(info[i].bmap->dim),
  466. info[i].bmap->n_div, n_eq, n_eq + n_ineq + extra_rows);
  467. fused = add_valid_constraints(fused, &info[i], 1 + total);
  468. fused = add_valid_constraints(fused, &info[j], 1 + total);
  469. if (!fused)
  470. goto error;
  471. if (ISL_F_ISSET(info[i].bmap, ISL_BASIC_MAP_RATIONAL) &&
  472. ISL_F_ISSET(info[j].bmap, ISL_BASIC_MAP_RATIONAL))
  473. ISL_F_SET(fused, ISL_BASIC_MAP_RATIONAL);
  474. for (k = 0; k < info[i].bmap->n_div; ++k) {
  475. int l = isl_basic_map_alloc_div(fused);
  476. if (l < 0)
  477. goto error;
  478. if (isl_seq_eq(info[i].bmap->div[k], info[j].bmap->div[k],
  479. 1 + 1 + total)) {
  480. isl_seq_cpy(fused->div[l], info[i].bmap->div[k],
  481. 1 + 1 + total);
  482. } else {
  483. isl_int_set_si(fused->div[l][0], 0);
  484. simplify = 1;
  485. }
  486. }
  487. for (k = 0; k < extra_rows; ++k) {
  488. l = isl_basic_map_alloc_inequality(fused);
  489. if (l < 0)
  490. goto error;
  491. isl_seq_cpy(fused->ineq[l], extra->row[k], 1 + total);
  492. }
  493. if (detect_equalities)
  494. fused = isl_basic_map_detect_inequality_pairs(fused, NULL);
  495. fused = isl_basic_map_gauss(fused, NULL);
  496. if (simplify || info[j].simplify) {
  497. fused = isl_basic_map_simplify(fused);
  498. info[i].simplify = 0;
  499. } else if (extra_rows > 0) {
  500. fused = isl_basic_map_eliminate_pure_unit_divs(fused);
  501. }
  502. fused = isl_basic_map_finalize(fused);
  503. fused_tab = isl_tab_from_basic_map(fused, 0);
  504. if (isl_tab_detect_redundant(fused_tab) < 0)
  505. goto error;
  506. if (check_number &&
  507. number_of_constraints_increases(i, j, info, fused, fused_tab)) {
  508. isl_tab_free(fused_tab);
  509. isl_basic_map_free(fused);
  510. return isl_change_none;
  511. }
  512. clear(&info[i]);
  513. info[i].bmap = fused;
  514. info[i].tab = fused_tab;
  515. info[i].modified = 1;
  516. drop(&info[j]);
  517. return isl_change_fuse;
  518. error:
  519. isl_tab_free(fused_tab);
  520. isl_basic_map_free(fused);
  521. return isl_change_error;
  522. }
  523. /* Given a pair of basic maps i and j such that all constraints are either
  524. * "valid" or "cut", check if the facets corresponding to the "cut"
  525. * constraints of i lie entirely within basic map j.
  526. * If so, replace the pair by the basic map consisting of the valid
  527. * constraints in both basic maps.
  528. * Checking whether the facet lies entirely within basic map j
  529. * is performed by checking whether the constraints of basic map j
  530. * are valid for the facet. These tests are performed on a rational
  531. * tableau to avoid the theoretical possibility that a constraint
  532. * that was considered to be a cut constraint for the entire basic map i
  533. * happens to be considered to be a valid constraint for the facet,
  534. * even though it cuts off the same rational points.
  535. *
  536. * To see that we are not introducing any extra points, call the
  537. * two basic maps A and B and the resulting map U and let x
  538. * be an element of U \setminus ( A \cup B ).
  539. * A line connecting x with an element of A \cup B meets a facet F
  540. * of either A or B. Assume it is a facet of B and let c_1 be
  541. * the corresponding facet constraint. We have c_1(x) < 0 and
  542. * so c_1 is a cut constraint. This implies that there is some
  543. * (possibly rational) point x' satisfying the constraints of A
  544. * and the opposite of c_1 as otherwise c_1 would have been marked
  545. * valid for A. The line connecting x and x' meets a facet of A
  546. * in a (possibly rational) point that also violates c_1, but this
  547. * is impossible since all cut constraints of B are valid for all
  548. * cut facets of A.
  549. * In case F is a facet of A rather than B, then we can apply the
  550. * above reasoning to find a facet of B separating x from A \cup B first.
  551. */
  552. static enum isl_change check_facets(int i, int j,
  553. struct isl_coalesce_info *info)
  554. {
  555. int k, l;
  556. struct isl_tab_undo *snap, *snap2;
  557. unsigned n_eq = info[i].bmap->n_eq;
  558. snap = isl_tab_snap(info[i].tab);
  559. if (isl_tab_mark_rational(info[i].tab) < 0)
  560. return isl_change_error;
  561. snap2 = isl_tab_snap(info[i].tab);
  562. for (k = 0; k < info[i].bmap->n_ineq; ++k) {
  563. if (info[i].ineq[k] != STATUS_CUT)
  564. continue;
  565. if (isl_tab_select_facet(info[i].tab, n_eq + k) < 0)
  566. return isl_change_error;
  567. for (l = 0; l < info[j].bmap->n_ineq; ++l) {
  568. int stat;
  569. if (info[j].ineq[l] != STATUS_CUT)
  570. continue;
  571. stat = status_in(info[j].bmap->ineq[l], info[i].tab);
  572. if (stat < 0)
  573. return isl_change_error;
  574. if (stat != STATUS_VALID)
  575. break;
  576. }
  577. if (isl_tab_rollback(info[i].tab, snap2) < 0)
  578. return isl_change_error;
  579. if (l < info[j].bmap->n_ineq)
  580. break;
  581. }
  582. if (k < info[i].bmap->n_ineq) {
  583. if (isl_tab_rollback(info[i].tab, snap) < 0)
  584. return isl_change_error;
  585. return isl_change_none;
  586. }
  587. return fuse(i, j, info, NULL, 0, 0);
  588. }
  589. /* Check if info->bmap contains the basic map represented
  590. * by the tableau "tab".
  591. * For each equality, we check both the constraint itself
  592. * (as an inequality) and its negation. Make sure the
  593. * equality is returned to its original state before returning.
  594. */
  595. static isl_bool contains(struct isl_coalesce_info *info, struct isl_tab *tab)
  596. {
  597. int k;
  598. isl_size dim;
  599. isl_basic_map *bmap = info->bmap;
  600. dim = isl_basic_map_dim(bmap, isl_dim_all);
  601. if (dim < 0)
  602. return isl_bool_error;
  603. for (k = 0; k < bmap->n_eq; ++k) {
  604. int stat;
  605. isl_seq_neg(bmap->eq[k], bmap->eq[k], 1 + dim);
  606. stat = status_in(bmap->eq[k], tab);
  607. isl_seq_neg(bmap->eq[k], bmap->eq[k], 1 + dim);
  608. if (stat < 0)
  609. return isl_bool_error;
  610. if (stat != STATUS_VALID)
  611. return isl_bool_false;
  612. stat = status_in(bmap->eq[k], tab);
  613. if (stat < 0)
  614. return isl_bool_error;
  615. if (stat != STATUS_VALID)
  616. return isl_bool_false;
  617. }
  618. for (k = 0; k < bmap->n_ineq; ++k) {
  619. int stat;
  620. if (info->ineq[k] == STATUS_REDUNDANT)
  621. continue;
  622. stat = status_in(bmap->ineq[k], tab);
  623. if (stat < 0)
  624. return isl_bool_error;
  625. if (stat != STATUS_VALID)
  626. return isl_bool_false;
  627. }
  628. return isl_bool_true;
  629. }
  630. /* Basic map "i" has an inequality "k" that is adjacent
  631. * to some inequality of basic map "j". All the other inequalities
  632. * are valid for "j".
  633. * If not NULL, then "extra" contains extra wrapping constraints that are valid
  634. * for both "i" and "j".
  635. * Check if basic map "j" forms an extension of basic map "i",
  636. * taking into account the extra constraints, if any.
  637. *
  638. * Note that this function is only called if some of the equalities or
  639. * inequalities of basic map "j" do cut basic map "i". The function is
  640. * correct even if there are no such cut constraints, but in that case
  641. * the additional checks performed by this function are overkill.
  642. *
  643. * In particular, we replace constraint k, say f >= 0, by constraint
  644. * f <= -1, add the inequalities of "j" that are valid for "i",
  645. * as well as the "extra" constraints, if any,
  646. * and check if the result is a subset of basic map "j".
  647. * To improve the chances of the subset relation being detected,
  648. * any variable that only attains a single integer value
  649. * in the tableau of "i" is first fixed to that value.
  650. * If the result is a subset, then we know that this result is exactly equal
  651. * to basic map "j" since all its constraints are valid for basic map "j".
  652. * By combining the valid constraints of "i" (all equalities and all
  653. * inequalities except "k"), the valid constraints of "j" and
  654. * the "extra" constraints, if any, we therefore
  655. * obtain a basic map that is equal to their union.
  656. * In this case, there is no need to perform a rollback of the tableau
  657. * since it is going to be destroyed in fuse().
  658. *
  659. *
  660. * |\__ |\__
  661. * | \__ | \__
  662. * | \_ => | \__
  663. * |_______| _ |_________\
  664. *
  665. *
  666. * |\ |\
  667. * | \ | \
  668. * | \ | \
  669. * | | | \
  670. * | ||\ => | \
  671. * | || \ | \
  672. * | || | | |
  673. * |__||_/ |_____/
  674. *
  675. *
  676. * _______ _______
  677. * | | __ | \__
  678. * | ||__| => | __|
  679. * |_______| |_______/
  680. */
  681. static enum isl_change is_adj_ineq_extension_with_wraps(int i, int j, int k,
  682. struct isl_coalesce_info *info, __isl_keep isl_mat *extra)
  683. {
  684. struct isl_tab_undo *snap;
  685. isl_size n_eq_i, n_ineq_j, n_extra;
  686. isl_size total = isl_basic_map_dim(info[i].bmap, isl_dim_all);
  687. isl_stat r;
  688. isl_bool super;
  689. if (total < 0)
  690. return isl_change_error;
  691. n_eq_i = isl_basic_map_n_equality(info[i].bmap);
  692. n_ineq_j = isl_basic_map_n_inequality(info[j].bmap);
  693. n_extra = isl_mat_rows(extra);
  694. if (n_eq_i < 0 || n_ineq_j < 0 || n_extra < 0)
  695. return isl_change_error;
  696. if (isl_tab_extend_cons(info[i].tab, 1 + n_ineq_j + n_extra) < 0)
  697. return isl_change_error;
  698. snap = isl_tab_snap(info[i].tab);
  699. if (isl_tab_unrestrict(info[i].tab, n_eq_i + k) < 0)
  700. return isl_change_error;
  701. isl_seq_neg(info[i].bmap->ineq[k], info[i].bmap->ineq[k], 1 + total);
  702. isl_int_sub_ui(info[i].bmap->ineq[k][0], info[i].bmap->ineq[k][0], 1);
  703. r = isl_tab_add_ineq(info[i].tab, info[i].bmap->ineq[k]);
  704. isl_seq_neg(info[i].bmap->ineq[k], info[i].bmap->ineq[k], 1 + total);
  705. isl_int_sub_ui(info[i].bmap->ineq[k][0], info[i].bmap->ineq[k][0], 1);
  706. if (r < 0)
  707. return isl_change_error;
  708. for (k = 0; k < n_ineq_j; ++k) {
  709. if (info[j].ineq[k] != STATUS_VALID)
  710. continue;
  711. if (isl_tab_add_ineq(info[i].tab, info[j].bmap->ineq[k]) < 0)
  712. return isl_change_error;
  713. }
  714. for (k = 0; k < n_extra; ++k) {
  715. if (isl_tab_add_ineq(info[i].tab, extra->row[k]) < 0)
  716. return isl_change_error;
  717. }
  718. if (isl_tab_detect_constants(info[i].tab) < 0)
  719. return isl_change_error;
  720. super = contains(&info[j], info[i].tab);
  721. if (super < 0)
  722. return isl_change_error;
  723. if (super)
  724. return fuse(i, j, info, extra, 0, 0);
  725. if (isl_tab_rollback(info[i].tab, snap) < 0)
  726. return isl_change_error;
  727. return isl_change_none;
  728. }
  729. /* Given an affine transformation matrix "T", does row "row" represent
  730. * anything other than a unit vector (possibly shifted by a constant)
  731. * that is not involved in any of the other rows?
  732. *
  733. * That is, if a constraint involves the variable corresponding to
  734. * the row, then could its preimage by "T" have any coefficients
  735. * that are different from those in the original constraint?
  736. */
  737. static int not_unique_unit_row(__isl_keep isl_mat *T, int row)
  738. {
  739. int i, j;
  740. int len = T->n_col - 1;
  741. i = isl_seq_first_non_zero(T->row[row] + 1, len);
  742. if (i < 0)
  743. return 1;
  744. if (!isl_int_is_one(T->row[row][1 + i]) &&
  745. !isl_int_is_negone(T->row[row][1 + i]))
  746. return 1;
  747. j = isl_seq_first_non_zero(T->row[row] + 1 + i + 1, len - (i + 1));
  748. if (j >= 0)
  749. return 1;
  750. for (j = 1; j < T->n_row; ++j) {
  751. if (j == row)
  752. continue;
  753. if (!isl_int_is_zero(T->row[j][1 + i]))
  754. return 1;
  755. }
  756. return 0;
  757. }
  758. /* Does inequality constraint "ineq" of "bmap" involve any of
  759. * the variables marked in "affected"?
  760. * "total" is the total number of variables, i.e., the number
  761. * of entries in "affected".
  762. */
  763. static isl_bool is_affected(__isl_keep isl_basic_map *bmap, int ineq,
  764. int *affected, int total)
  765. {
  766. int i;
  767. for (i = 0; i < total; ++i) {
  768. if (!affected[i])
  769. continue;
  770. if (!isl_int_is_zero(bmap->ineq[ineq][1 + i]))
  771. return isl_bool_true;
  772. }
  773. return isl_bool_false;
  774. }
  775. /* Given the compressed version of inequality constraint "ineq"
  776. * of info->bmap in "v", check if the constraint can be tightened,
  777. * where the compression is based on an equality constraint valid
  778. * for info->tab.
  779. * If so, add the tightened version of the inequality constraint
  780. * to info->tab. "v" may be modified by this function.
  781. *
  782. * That is, if the compressed constraint is of the form
  783. *
  784. * m f() + c >= 0
  785. *
  786. * with 0 < c < m, then it is equivalent to
  787. *
  788. * f() >= 0
  789. *
  790. * This means that c can also be subtracted from the original,
  791. * uncompressed constraint without affecting the integer points
  792. * in info->tab. Add this tightened constraint as an extra row
  793. * to info->tab to make this information explicitly available.
  794. */
  795. static __isl_give isl_vec *try_tightening(struct isl_coalesce_info *info,
  796. int ineq, __isl_take isl_vec *v)
  797. {
  798. isl_ctx *ctx;
  799. isl_stat r;
  800. if (!v)
  801. return NULL;
  802. ctx = isl_vec_get_ctx(v);
  803. isl_seq_gcd(v->el + 1, v->size - 1, &ctx->normalize_gcd);
  804. if (isl_int_is_zero(ctx->normalize_gcd) ||
  805. isl_int_is_one(ctx->normalize_gcd)) {
  806. return v;
  807. }
  808. v = isl_vec_cow(v);
  809. if (!v)
  810. return NULL;
  811. isl_int_fdiv_r(v->el[0], v->el[0], ctx->normalize_gcd);
  812. if (isl_int_is_zero(v->el[0]))
  813. return v;
  814. if (isl_tab_extend_cons(info->tab, 1) < 0)
  815. return isl_vec_free(v);
  816. isl_int_sub(info->bmap->ineq[ineq][0],
  817. info->bmap->ineq[ineq][0], v->el[0]);
  818. r = isl_tab_add_ineq(info->tab, info->bmap->ineq[ineq]);
  819. isl_int_add(info->bmap->ineq[ineq][0],
  820. info->bmap->ineq[ineq][0], v->el[0]);
  821. if (r < 0)
  822. return isl_vec_free(v);
  823. return v;
  824. }
  825. /* Tighten the (non-redundant) constraints on the facet represented
  826. * by info->tab.
  827. * In particular, on input, info->tab represents the result
  828. * of relaxing the "n" inequality constraints of info->bmap in "relaxed"
  829. * by one, i.e., replacing f_i >= 0 by f_i + 1 >= 0, and then
  830. * replacing the one at index "l" by the corresponding equality,
  831. * i.e., f_k + 1 = 0, with k = relaxed[l].
  832. *
  833. * Compute a variable compression from the equality constraint f_k + 1 = 0
  834. * and use it to tighten the other constraints of info->bmap
  835. * (that is, all constraints that have not been relaxed),
  836. * updating info->tab (and leaving info->bmap untouched).
  837. * The compression handles essentially two cases, one where a variable
  838. * is assigned a fixed value and can therefore be eliminated, and one
  839. * where one variable is a shifted multiple of some other variable and
  840. * can therefore be replaced by that multiple.
  841. * Gaussian elimination would also work for the first case, but for
  842. * the second case, the effectiveness would depend on the order
  843. * of the variables.
  844. * After compression, some of the constraints may have coefficients
  845. * with a common divisor. If this divisor does not divide the constant
  846. * term, then the constraint can be tightened.
  847. * The tightening is performed on the tableau info->tab by introducing
  848. * extra (temporary) constraints.
  849. *
  850. * Only constraints that are possibly affected by the compression are
  851. * considered. In particular, if the constraint only involves variables
  852. * that are directly mapped to a distinct set of other variables, then
  853. * no common divisor can be introduced and no tightening can occur.
  854. *
  855. * It is important to only consider the non-redundant constraints
  856. * since the facet constraint has been relaxed prior to the call
  857. * to this function, meaning that the constraints that were redundant
  858. * prior to the relaxation may no longer be redundant.
  859. * These constraints will be ignored in the fused result, so
  860. * the fusion detection should not exploit them.
  861. */
  862. static isl_stat tighten_on_relaxed_facet(struct isl_coalesce_info *info,
  863. int n, int *relaxed, int l)
  864. {
  865. isl_size total;
  866. isl_ctx *ctx;
  867. isl_vec *v = NULL;
  868. isl_mat *T;
  869. int i;
  870. int k;
  871. int *affected;
  872. k = relaxed[l];
  873. ctx = isl_basic_map_get_ctx(info->bmap);
  874. total = isl_basic_map_dim(info->bmap, isl_dim_all);
  875. if (total < 0)
  876. return isl_stat_error;
  877. isl_int_add_ui(info->bmap->ineq[k][0], info->bmap->ineq[k][0], 1);
  878. T = isl_mat_sub_alloc6(ctx, info->bmap->ineq, k, 1, 0, 1 + total);
  879. T = isl_mat_variable_compression(T, NULL);
  880. isl_int_sub_ui(info->bmap->ineq[k][0], info->bmap->ineq[k][0], 1);
  881. if (!T)
  882. return isl_stat_error;
  883. if (T->n_col == 0) {
  884. isl_mat_free(T);
  885. return isl_stat_ok;
  886. }
  887. affected = isl_alloc_array(ctx, int, total);
  888. if (!affected)
  889. goto error;
  890. for (i = 0; i < total; ++i)
  891. affected[i] = not_unique_unit_row(T, 1 + i);
  892. for (i = 0; i < info->bmap->n_ineq; ++i) {
  893. isl_bool handle;
  894. if (any(relaxed, n, i))
  895. continue;
  896. if (info->ineq[i] == STATUS_REDUNDANT)
  897. continue;
  898. handle = is_affected(info->bmap, i, affected, total);
  899. if (handle < 0)
  900. goto error;
  901. if (!handle)
  902. continue;
  903. v = isl_vec_alloc(ctx, 1 + total);
  904. if (!v)
  905. goto error;
  906. isl_seq_cpy(v->el, info->bmap->ineq[i], 1 + total);
  907. v = isl_vec_mat_product(v, isl_mat_copy(T));
  908. v = try_tightening(info, i, v);
  909. isl_vec_free(v);
  910. if (!v)
  911. goto error;
  912. }
  913. isl_mat_free(T);
  914. free(affected);
  915. return isl_stat_ok;
  916. error:
  917. isl_mat_free(T);
  918. free(affected);
  919. return isl_stat_error;
  920. }
  921. /* Replace the basic maps "i" and "j" by an extension of "i"
  922. * along the "n" inequality constraints in "relax" by one.
  923. * The tableau info[i].tab has already been extended.
  924. * Extend info[i].bmap accordingly by relaxing all constraints in "relax"
  925. * by one.
  926. * Each integer division that does not have exactly the same
  927. * definition in "i" and "j" is marked unknown and the basic map
  928. * is scheduled to be simplified in an attempt to recover
  929. * the integer division definition.
  930. * Place the extension in the position that is the smallest of i and j.
  931. */
  932. static enum isl_change extend(int i, int j, int n, int *relax,
  933. struct isl_coalesce_info *info)
  934. {
  935. int l;
  936. isl_size total;
  937. info[i].bmap = isl_basic_map_cow(info[i].bmap);
  938. total = isl_basic_map_dim(info[i].bmap, isl_dim_all);
  939. if (total < 0)
  940. return isl_change_error;
  941. for (l = 0; l < info[i].bmap->n_div; ++l)
  942. if (!isl_seq_eq(info[i].bmap->div[l],
  943. info[j].bmap->div[l], 1 + 1 + total)) {
  944. isl_int_set_si(info[i].bmap->div[l][0], 0);
  945. info[i].simplify = 1;
  946. }
  947. for (l = 0; l < n; ++l)
  948. isl_int_add_ui(info[i].bmap->ineq[relax[l]][0],
  949. info[i].bmap->ineq[relax[l]][0], 1);
  950. ISL_F_CLR(info[i].bmap, ISL_BASIC_MAP_NO_REDUNDANT);
  951. ISL_F_SET(info[i].bmap, ISL_BASIC_MAP_FINAL);
  952. drop(&info[j]);
  953. info[i].modified = 1;
  954. if (j < i)
  955. exchange(&info[i], &info[j]);
  956. return isl_change_fuse;
  957. }
  958. /* Basic map "i" has "n" inequality constraints (collected in "relax")
  959. * that are such that they include basic map "j" if they are relaxed
  960. * by one. All the other inequalities are valid for "j".
  961. * Check if basic map "j" forms an extension of basic map "i".
  962. *
  963. * In particular, relax the constraints in "relax", compute the corresponding
  964. * facets one by one and check whether each of these is included
  965. * in the other basic map.
  966. * Before testing for inclusion, the constraints on each facet
  967. * are tightened to increase the chance of an inclusion being detected.
  968. * (Adding the valid constraints of "j" to the tableau of "i", as is done
  969. * in is_adj_ineq_extension, may further increase those chances, but this
  970. * is not currently done.)
  971. * If each facet is included, we know that relaxing the constraints extends
  972. * the basic map with exactly the other basic map (we already know that this
  973. * other basic map is included in the extension, because all other
  974. * inequality constraints are valid of "j") and we can replace the
  975. * two basic maps by this extension.
  976. *
  977. * If any of the relaxed constraints turn out to be redundant, then bail out.
  978. * isl_tab_select_facet refuses to handle such constraints. It may be
  979. * possible to handle them anyway by making a distinction between
  980. * redundant constraints with a corresponding facet that still intersects
  981. * the set (allowing isl_tab_select_facet to handle them) and
  982. * those where the facet does not intersect the set (which can be ignored
  983. * because the empty facet is trivially included in the other disjunct).
  984. * However, relaxed constraints that turn out to be redundant should
  985. * be fairly rare and no such instance has been reported where
  986. * coalescing would be successful.
  987. * ____ _____
  988. * / || / |
  989. * / || / |
  990. * \ || => \ |
  991. * \ || \ |
  992. * \___|| \____|
  993. *
  994. *
  995. * \ |\
  996. * |\\ | \
  997. * | \\ | \
  998. * | | => | /
  999. * | / | /
  1000. * |/ |/
  1001. */
  1002. static enum isl_change is_relaxed_extension(int i, int j, int n, int *relax,
  1003. struct isl_coalesce_info *info)
  1004. {
  1005. int l;
  1006. isl_bool super;
  1007. struct isl_tab_undo *snap, *snap2;
  1008. unsigned n_eq = info[i].bmap->n_eq;
  1009. for (l = 0; l < n; ++l)
  1010. if (isl_tab_is_equality(info[i].tab, n_eq + relax[l]))
  1011. return isl_change_none;
  1012. snap = isl_tab_snap(info[i].tab);
  1013. for (l = 0; l < n; ++l)
  1014. if (isl_tab_relax(info[i].tab, n_eq + relax[l]) < 0)
  1015. return isl_change_error;
  1016. for (l = 0; l < n; ++l) {
  1017. if (!isl_tab_is_redundant(info[i].tab, n_eq + relax[l]))
  1018. continue;
  1019. if (isl_tab_rollback(info[i].tab, snap) < 0)
  1020. return isl_change_error;
  1021. return isl_change_none;
  1022. }
  1023. snap2 = isl_tab_snap(info[i].tab);
  1024. for (l = 0; l < n; ++l) {
  1025. if (isl_tab_rollback(info[i].tab, snap2) < 0)
  1026. return isl_change_error;
  1027. if (isl_tab_select_facet(info[i].tab, n_eq + relax[l]) < 0)
  1028. return isl_change_error;
  1029. if (tighten_on_relaxed_facet(&info[i], n, relax, l) < 0)
  1030. return isl_change_error;
  1031. super = contains(&info[j], info[i].tab);
  1032. if (super < 0)
  1033. return isl_change_error;
  1034. if (super)
  1035. continue;
  1036. if (isl_tab_rollback(info[i].tab, snap) < 0)
  1037. return isl_change_error;
  1038. return isl_change_none;
  1039. }
  1040. if (isl_tab_rollback(info[i].tab, snap2) < 0)
  1041. return isl_change_error;
  1042. return extend(i, j, n, relax, info);
  1043. }
  1044. /* Data structure that keeps track of the wrapping constraints
  1045. * and of information to bound the coefficients of those constraints.
  1046. *
  1047. * "failed" is set if wrapping has failed.
  1048. * bound is set if we want to apply a bound on the coefficients
  1049. * mat contains the wrapping constraints
  1050. * max is the bound on the coefficients (if bound is set)
  1051. */
  1052. struct isl_wraps {
  1053. int failed;
  1054. int bound;
  1055. isl_mat *mat;
  1056. isl_int max;
  1057. };
  1058. /* Update wraps->max to be greater than or equal to the coefficients
  1059. * in the equalities and inequalities of info->bmap that can be removed
  1060. * if we end up applying wrapping.
  1061. */
  1062. static isl_stat wraps_update_max(struct isl_wraps *wraps,
  1063. struct isl_coalesce_info *info)
  1064. {
  1065. int k;
  1066. isl_int max_k;
  1067. isl_size total = isl_basic_map_dim(info->bmap, isl_dim_all);
  1068. if (total < 0)
  1069. return isl_stat_error;
  1070. isl_int_init(max_k);
  1071. for (k = 0; k < info->bmap->n_eq; ++k) {
  1072. if (info->eq[2 * k] == STATUS_VALID &&
  1073. info->eq[2 * k + 1] == STATUS_VALID)
  1074. continue;
  1075. isl_seq_abs_max(info->bmap->eq[k] + 1, total, &max_k);
  1076. if (isl_int_abs_gt(max_k, wraps->max))
  1077. isl_int_set(wraps->max, max_k);
  1078. }
  1079. for (k = 0; k < info->bmap->n_ineq; ++k) {
  1080. if (info->ineq[k] == STATUS_VALID ||
  1081. info->ineq[k] == STATUS_REDUNDANT)
  1082. continue;
  1083. isl_seq_abs_max(info->bmap->ineq[k] + 1, total, &max_k);
  1084. if (isl_int_abs_gt(max_k, wraps->max))
  1085. isl_int_set(wraps->max, max_k);
  1086. }
  1087. isl_int_clear(max_k);
  1088. return isl_stat_ok;
  1089. }
  1090. /* Initialize the isl_wraps data structure.
  1091. * If we want to bound the coefficients of the wrapping constraints,
  1092. * we set wraps->max to the largest coefficient
  1093. * in the equalities and inequalities that can be removed if we end up
  1094. * applying wrapping.
  1095. */
  1096. static isl_stat wraps_init(struct isl_wraps *wraps, __isl_take isl_mat *mat,
  1097. struct isl_coalesce_info *info, int i, int j)
  1098. {
  1099. isl_ctx *ctx;
  1100. wraps->failed = 0;
  1101. wraps->bound = 0;
  1102. wraps->mat = mat;
  1103. if (!mat)
  1104. return isl_stat_error;
  1105. wraps->mat->n_row = 0;
  1106. ctx = isl_mat_get_ctx(mat);
  1107. wraps->bound = isl_options_get_coalesce_bounded_wrapping(ctx);
  1108. if (!wraps->bound)
  1109. return isl_stat_ok;
  1110. isl_int_init(wraps->max);
  1111. isl_int_set_si(wraps->max, 0);
  1112. if (wraps_update_max(wraps, &info[i]) < 0)
  1113. return isl_stat_error;
  1114. if (wraps_update_max(wraps, &info[j]) < 0)
  1115. return isl_stat_error;
  1116. return isl_stat_ok;
  1117. }
  1118. /* Free the contents of the isl_wraps data structure.
  1119. */
  1120. static void wraps_free(struct isl_wraps *wraps)
  1121. {
  1122. isl_mat_free(wraps->mat);
  1123. if (wraps->bound)
  1124. isl_int_clear(wraps->max);
  1125. }
  1126. /* Mark the wrapping as failed.
  1127. */
  1128. static isl_stat wraps_mark_failed(struct isl_wraps *wraps)
  1129. {
  1130. wraps->failed = 1;
  1131. return isl_stat_ok;
  1132. }
  1133. /* Is the wrapping constraint in row "row" allowed?
  1134. *
  1135. * If wraps->bound is set, we check that none of the coefficients
  1136. * is greater than wraps->max.
  1137. */
  1138. static int allow_wrap(struct isl_wraps *wraps, int row)
  1139. {
  1140. int i;
  1141. if (!wraps->bound)
  1142. return 1;
  1143. for (i = 1; i < wraps->mat->n_col; ++i)
  1144. if (isl_int_abs_gt(wraps->mat->row[row][i], wraps->max))
  1145. return 0;
  1146. return 1;
  1147. }
  1148. /* Wrap "ineq" (or its opposite if "negate" is set) around "bound"
  1149. * to include "set" and add the result in position "w" of "wraps".
  1150. * "len" is the total number of coefficients in "bound" and "ineq".
  1151. * Return 1 on success, 0 on failure and -1 on error.
  1152. * Wrapping can fail if the result of wrapping is equal to "bound"
  1153. * or if we want to bound the sizes of the coefficients and
  1154. * the wrapped constraint does not satisfy this bound.
  1155. */
  1156. static int add_wrap(struct isl_wraps *wraps, int w, isl_int *bound,
  1157. isl_int *ineq, unsigned len, __isl_keep isl_set *set, int negate)
  1158. {
  1159. isl_seq_cpy(wraps->mat->row[w], bound, len);
  1160. if (negate) {
  1161. isl_seq_neg(wraps->mat->row[w + 1], ineq, len);
  1162. ineq = wraps->mat->row[w + 1];
  1163. }
  1164. if (!isl_set_wrap_facet(set, wraps->mat->row[w], ineq))
  1165. return -1;
  1166. if (isl_seq_eq(wraps->mat->row[w], bound, len))
  1167. return 0;
  1168. if (!allow_wrap(wraps, w))
  1169. return 0;
  1170. return 1;
  1171. }
  1172. /* This function has two modes of operations.
  1173. *
  1174. * If "add_valid" is set, then all the constraints of info->bmap
  1175. * (except the opposite of "bound") are valid for the other basic map.
  1176. * In this case, attempts are made to wrap some of these valid constraints
  1177. * to more tightly fit around "set". Only successful wrappings are recorded
  1178. * and failed wrappings are ignored.
  1179. *
  1180. * If "add_valid" is not set, then some of the constraints of info->bmap
  1181. * are not valid for the other basic map, and only those are considered
  1182. * for wrapping. In this case all attempted wrappings need to succeed.
  1183. * Otherwise "wraps" is marked as failed.
  1184. * Note that the constraints that are valid for the other basic map
  1185. * will be added to the combined basic map by default, so there is
  1186. * no need to wrap them.
  1187. * The caller wrap_in_facets even relies on this function not wrapping
  1188. * any constraints that are already valid.
  1189. *
  1190. * Only consider constraints that are not redundant (as determined
  1191. * by info->tab) and that are valid or invalid depending on "add_valid".
  1192. * Wrap each constraint around "bound" such that it includes the whole
  1193. * set "set" and append the resulting constraint to "wraps".
  1194. * "wraps" is assumed to have been pre-allocated to the appropriate size.
  1195. * wraps->n_row is the number of actual wrapped constraints that have
  1196. * been added.
  1197. * If any of the wrapping problems results in a constraint that is
  1198. * identical to "bound", then this means that "set" is unbounded in such
  1199. * a way that no wrapping is possible.
  1200. * Similarly, if we want to bound the coefficients of the wrapping
  1201. * constraints and a newly added wrapping constraint does not
  1202. * satisfy the bound, then the wrapping is considered to have failed.
  1203. * Note though that "wraps" is only marked failed if "add_valid" is not set.
  1204. */
  1205. static isl_stat add_selected_wraps(struct isl_wraps *wraps,
  1206. struct isl_coalesce_info *info, isl_int *bound, __isl_keep isl_set *set,
  1207. int add_valid)
  1208. {
  1209. int l, m;
  1210. int w;
  1211. int added;
  1212. isl_basic_map *bmap = info->bmap;
  1213. isl_size total = isl_basic_map_dim(bmap, isl_dim_all);
  1214. unsigned len = 1 + total;
  1215. if (total < 0)
  1216. return isl_stat_error;
  1217. w = wraps->mat->n_row;
  1218. for (l = 0; l < bmap->n_ineq; ++l) {
  1219. int is_valid = info->ineq[l] == STATUS_VALID;
  1220. if ((!add_valid && is_valid) ||
  1221. info->ineq[l] == STATUS_REDUNDANT)
  1222. continue;
  1223. if (isl_seq_is_neg(bound, bmap->ineq[l], len))
  1224. continue;
  1225. if (isl_seq_eq(bound, bmap->ineq[l], len))
  1226. continue;
  1227. if (isl_tab_is_redundant(info->tab, bmap->n_eq + l))
  1228. continue;
  1229. added = add_wrap(wraps, w, bound, bmap->ineq[l], len, set, 0);
  1230. if (added < 0)
  1231. return isl_stat_error;
  1232. if (!added && !is_valid)
  1233. goto unbounded;
  1234. if (added)
  1235. ++w;
  1236. }
  1237. for (l = 0; l < bmap->n_eq; ++l) {
  1238. if (isl_seq_is_neg(bound, bmap->eq[l], len))
  1239. continue;
  1240. if (isl_seq_eq(bound, bmap->eq[l], len))
  1241. continue;
  1242. for (m = 0; m < 2; ++m) {
  1243. if (info->eq[2 * l + m] == STATUS_VALID)
  1244. continue;
  1245. added = add_wrap(wraps, w, bound, bmap->eq[l], len,
  1246. set, !m);
  1247. if (added < 0)
  1248. return isl_stat_error;
  1249. if (!added)
  1250. goto unbounded;
  1251. ++w;
  1252. }
  1253. }
  1254. wraps->mat->n_row = w;
  1255. return isl_stat_ok;
  1256. unbounded:
  1257. return wraps_mark_failed(wraps);
  1258. }
  1259. /* For each constraint in info->bmap that is not redundant (as determined
  1260. * by info->tab) and that is not a valid constraint for the other basic map,
  1261. * wrap the constraint around "bound" such that it includes the whole
  1262. * set "set" and append the resulting constraint to "wraps".
  1263. * Note that the constraints that are valid for the other basic map
  1264. * will be added to the combined basic map by default, so there is
  1265. * no need to wrap them.
  1266. * The caller wrap_in_facets even relies on this function not wrapping
  1267. * any constraints that are already valid.
  1268. * "wraps" is assumed to have been pre-allocated to the appropriate size.
  1269. * wraps->n_row is the number of actual wrapped constraints that have
  1270. * been added.
  1271. * If any of the wrapping problems results in a constraint that is
  1272. * identical to "bound", then this means that "set" is unbounded in such
  1273. * a way that no wrapping is possible. If this happens then "wraps"
  1274. * is marked as failed.
  1275. * Similarly, if we want to bound the coefficients of the wrapping
  1276. * constraints and a newly added wrapping constraint does not
  1277. * satisfy the bound, then "wraps" is also marked as failed.
  1278. */
  1279. static isl_stat add_wraps(struct isl_wraps *wraps,
  1280. struct isl_coalesce_info *info, isl_int *bound, __isl_keep isl_set *set)
  1281. {
  1282. return add_selected_wraps(wraps, info, bound, set, 0);
  1283. }
  1284. /* Check if the constraints in "wraps" from "first" until the last
  1285. * are all valid for the basic set represented by "tab",
  1286. * dropping the invalid constraints if "keep" is set and
  1287. * marking the wrapping as failed if "keep" is not set and
  1288. * any constraint turns out to be invalid.
  1289. */
  1290. static isl_stat check_wraps(struct isl_wraps *wraps, int first,
  1291. struct isl_tab *tab, int keep)
  1292. {
  1293. int i;
  1294. for (i = wraps->mat->n_row - 1; i >= first; --i) {
  1295. enum isl_ineq_type type;
  1296. type = isl_tab_ineq_type(tab, wraps->mat->row[i]);
  1297. if (type == isl_ineq_error)
  1298. return isl_stat_error;
  1299. if (type == isl_ineq_redundant)
  1300. continue;
  1301. if (!keep)
  1302. return wraps_mark_failed(wraps);
  1303. wraps->mat = isl_mat_drop_rows(wraps->mat, i, 1);
  1304. if (!wraps->mat)
  1305. return isl_stat_error;
  1306. }
  1307. return isl_stat_ok;
  1308. }
  1309. /* Return a set that corresponds to the non-redundant constraints
  1310. * (as recorded in tab) of bmap.
  1311. *
  1312. * It's important to remove the redundant constraints as some
  1313. * of the other constraints may have been modified after the
  1314. * constraints were marked redundant.
  1315. * In particular, a constraint may have been relaxed.
  1316. * Redundant constraints are ignored when a constraint is relaxed
  1317. * and should therefore continue to be ignored ever after.
  1318. * Otherwise, the relaxation might be thwarted by some of
  1319. * these constraints.
  1320. *
  1321. * Update the underlying set to ensure that the dimension doesn't change.
  1322. * Otherwise the integer divisions could get dropped if the tab
  1323. * turns out to be empty.
  1324. */
  1325. static __isl_give isl_set *set_from_updated_bmap(__isl_keep isl_basic_map *bmap,
  1326. struct isl_tab *tab)
  1327. {
  1328. isl_basic_set *bset;
  1329. bmap = isl_basic_map_copy(bmap);
  1330. bset = isl_basic_map_underlying_set(bmap);
  1331. bset = isl_basic_set_cow(bset);
  1332. bset = isl_basic_set_update_from_tab(bset, tab);
  1333. return isl_set_from_basic_set(bset);
  1334. }
  1335. /* Does "info" have any cut constraints that are redundant?
  1336. */
  1337. static isl_bool has_redundant_cuts(struct isl_coalesce_info *info)
  1338. {
  1339. int l;
  1340. isl_size n_eq, n_ineq;
  1341. n_eq = isl_basic_map_n_equality(info->bmap);
  1342. n_ineq = isl_basic_map_n_inequality(info->bmap);
  1343. if (n_eq < 0 || n_ineq < 0)
  1344. return isl_bool_error;
  1345. for (l = 0; l < n_ineq; ++l) {
  1346. int red;
  1347. if (info->ineq[l] != STATUS_CUT)
  1348. continue;
  1349. red = isl_tab_is_redundant(info->tab, n_eq + l);
  1350. if (red < 0)
  1351. return isl_bool_error;
  1352. if (red)
  1353. return isl_bool_true;
  1354. }
  1355. return isl_bool_false;
  1356. }
  1357. /* Wrap some constraints of info->bmap that bound the facet defined
  1358. * by inequality "k" around (the opposite of) this inequality to
  1359. * include "set". "bound" may be used to store the negated inequality.
  1360. *
  1361. * If "add_valid" is set, then all ridges are already valid and
  1362. * the purpose is to wrap "set" more tightly. In this case,
  1363. * wrapping doesn't fail, although it is possible that no constraint
  1364. * gets wrapped.
  1365. *
  1366. * If "add_valid" is not set, then some of the ridges are cut constraints
  1367. * and only those are wrapped around "set".
  1368. *
  1369. * Since the wrapped constraints are not guaranteed to contain the whole
  1370. * of info->bmap, we check them in check_wraps.
  1371. * If any of the wrapped constraints turn out to be invalid, then
  1372. * check_wraps will mark "wraps" as failed if "add_valid" is not set.
  1373. * If "add_valid" is set, then the offending constraints are
  1374. * simply removed.
  1375. *
  1376. * If the facet turns out to be empty, then no wrapping can be performed.
  1377. * This is considered a failure, unless "add_valid" is set.
  1378. *
  1379. * If any of the cut constraints of info->bmap turn out
  1380. * to be redundant with respect to other constraints
  1381. * then these will neither be wrapped nor added directly to the result.
  1382. * The result may therefore not be correct.
  1383. * Skip wrapping and mark "wraps" as failed in this case.
  1384. */
  1385. static isl_stat add_selected_wraps_around_facet(struct isl_wraps *wraps,
  1386. struct isl_coalesce_info *info, int k, isl_int *bound,
  1387. __isl_keep isl_set *set, int add_valid)
  1388. {
  1389. isl_bool nowrap;
  1390. struct isl_tab_undo *snap;
  1391. int n;
  1392. isl_size total = isl_basic_map_dim(info->bmap, isl_dim_all);
  1393. if (total < 0)
  1394. return isl_stat_error;
  1395. snap = isl_tab_snap(info->tab);
  1396. if (isl_tab_select_facet(info->tab, info->bmap->n_eq + k) < 0)
  1397. return isl_stat_error;
  1398. if (isl_tab_detect_redundant(info->tab) < 0)
  1399. return isl_stat_error;
  1400. if (info->tab->empty) {
  1401. if (!add_valid)
  1402. return wraps_mark_failed(wraps);
  1403. return isl_stat_ok;
  1404. }
  1405. nowrap = has_redundant_cuts(info);
  1406. if (nowrap < 0)
  1407. return isl_stat_error;
  1408. n = wraps->mat->n_row;
  1409. if (!nowrap) {
  1410. isl_seq_neg(bound, info->bmap->ineq[k], 1 + total);
  1411. if (add_selected_wraps(wraps, info, bound, set, add_valid) < 0)
  1412. return isl_stat_error;
  1413. }
  1414. if (isl_tab_rollback(info->tab, snap) < 0)
  1415. return isl_stat_error;
  1416. if (nowrap)
  1417. return wraps_mark_failed(wraps);
  1418. if (check_wraps(wraps, n, info->tab, add_valid) < 0)
  1419. return isl_stat_error;
  1420. return isl_stat_ok;
  1421. }
  1422. /* Wrap the constraints of info->bmap that bound the facet defined
  1423. * by inequality "k" around (the opposite of) this inequality to
  1424. * include "set". "bound" may be used to store the negated inequality.
  1425. * If any of the wrapped constraints turn out to be invalid for info->bmap
  1426. * itself, then mark "wraps" as failed.
  1427. */
  1428. static isl_stat add_wraps_around_facet(struct isl_wraps *wraps,
  1429. struct isl_coalesce_info *info, int k, isl_int *bound,
  1430. __isl_keep isl_set *set)
  1431. {
  1432. return add_selected_wraps_around_facet(wraps, info, k, bound, set, 0);
  1433. }
  1434. /* Wrap the (valid) constraints of info->bmap that bound the facet defined
  1435. * by inequality "k" around (the opposite of) this inequality to
  1436. * include "set" more tightly.
  1437. * "bound" may be used to store the negated inequality.
  1438. * Remove any wrapping constraints that turn out to be invalid
  1439. * for info->bmap itself.
  1440. */
  1441. static isl_stat add_valid_wraps_around_facet(struct isl_wraps *wraps,
  1442. struct isl_coalesce_info *info, int k, isl_int *bound,
  1443. __isl_keep isl_set *set)
  1444. {
  1445. return add_selected_wraps_around_facet(wraps, info, k, bound, set, 1);
  1446. }
  1447. /* Basic map "i" has an inequality (say "k") that is adjacent
  1448. * to some inequality of basic map "j". All the other inequalities
  1449. * are valid for "j".
  1450. * Check if basic map "j" forms an extension of basic map "i".
  1451. *
  1452. * Note that this function is only called if some of the equalities or
  1453. * inequalities of basic map "j" do cut basic map "i". The function is
  1454. * correct even if there are no such cut constraints, but in that case
  1455. * the additional checks performed by this function are overkill.
  1456. *
  1457. * First try and wrap the ridges of "k" around "j".
  1458. * Note that those ridges are already valid for "j",
  1459. * but the wrapped versions may wrap "j" more tightly,
  1460. * increasing the chances of "j" being detected as an extension of "i"
  1461. */
  1462. static enum isl_change is_adj_ineq_extension(int i, int j,
  1463. struct isl_coalesce_info *info)
  1464. {
  1465. int k;
  1466. enum isl_change change;
  1467. isl_size total;
  1468. isl_size n_eq_i, n_ineq_i;
  1469. struct isl_wraps wraps;
  1470. isl_ctx *ctx;
  1471. isl_mat *mat;
  1472. isl_vec *bound;
  1473. isl_set *set_j;
  1474. isl_stat r;
  1475. k = find_ineq(&info[i], STATUS_ADJ_INEQ);
  1476. if (k < 0)
  1477. isl_die(isl_basic_map_get_ctx(info[i].bmap), isl_error_internal,
  1478. "info[i].ineq should have exactly one STATUS_ADJ_INEQ",
  1479. return isl_change_error);
  1480. total = isl_basic_map_dim(info[i].bmap, isl_dim_all);
  1481. n_eq_i = isl_basic_map_n_equality(info[i].bmap);
  1482. n_ineq_i = isl_basic_map_n_inequality(info[i].bmap);
  1483. if (total < 0 || n_eq_i < 0 || n_ineq_i < 0)
  1484. return isl_change_error;
  1485. set_j = set_from_updated_bmap(info[j].bmap, info[j].tab);
  1486. ctx = isl_basic_map_get_ctx(info[i].bmap);
  1487. bound = isl_vec_alloc(ctx, 1 + total);
  1488. mat = isl_mat_alloc(ctx, 2 * n_eq_i + n_ineq_i, 1 + total);
  1489. if (wraps_init(&wraps, mat, info, i, j) < 0)
  1490. goto error;
  1491. if (!bound || !set_j)
  1492. goto error;
  1493. r = add_valid_wraps_around_facet(&wraps, &info[i], k, bound->el, set_j);
  1494. if (r < 0)
  1495. goto error;
  1496. change = is_adj_ineq_extension_with_wraps(i, j, k, info, wraps.mat);
  1497. wraps_free(&wraps);
  1498. isl_vec_free(bound);
  1499. isl_set_free(set_j);
  1500. return change;
  1501. error:
  1502. wraps_free(&wraps);
  1503. isl_vec_free(bound);
  1504. isl_set_free(set_j);
  1505. return isl_change_error;
  1506. }
  1507. /* Both basic maps have at least one inequality with and adjacent
  1508. * (but opposite) inequality in the other basic map.
  1509. * Check that there are no cut constraints and that there is only
  1510. * a single pair of adjacent inequalities.
  1511. * If so, we can replace the pair by a single basic map described
  1512. * by all but the pair of adjacent inequalities.
  1513. * Any additional points introduced lie strictly between the two
  1514. * adjacent hyperplanes and can therefore be integral.
  1515. *
  1516. * ____ _____
  1517. * / ||\ / \
  1518. * / || \ / \
  1519. * \ || \ => \ \
  1520. * \ || / \ /
  1521. * \___||_/ \_____/
  1522. *
  1523. * The test for a single pair of adjacent inequalities is important
  1524. * for avoiding the combination of two basic maps like the following
  1525. *
  1526. * /|
  1527. * / |
  1528. * /__|
  1529. * _____
  1530. * | |
  1531. * | |
  1532. * |___|
  1533. *
  1534. * If there are some cut constraints on one side, then we may
  1535. * still be able to fuse the two basic maps, but we need to perform
  1536. * some additional checks in is_adj_ineq_extension.
  1537. */
  1538. static enum isl_change check_adj_ineq(int i, int j,
  1539. struct isl_coalesce_info *info)
  1540. {
  1541. int count_i, count_j;
  1542. int cut_i, cut_j;
  1543. count_i = count_ineq(&info[i], STATUS_ADJ_INEQ);
  1544. count_j = count_ineq(&info[j], STATUS_ADJ_INEQ);
  1545. if (count_i != 1 && count_j != 1)
  1546. return isl_change_none;
  1547. cut_i = any_eq(&info[i], STATUS_CUT) || any_ineq(&info[i], STATUS_CUT);
  1548. cut_j = any_eq(&info[j], STATUS_CUT) || any_ineq(&info[j], STATUS_CUT);
  1549. if (!cut_i && !cut_j && count_i == 1 && count_j == 1)
  1550. return fuse(i, j, info, NULL, 0, 0);
  1551. if (count_i == 1 && !cut_i)
  1552. return is_adj_ineq_extension(i, j, info);
  1553. if (count_j == 1 && !cut_j)
  1554. return is_adj_ineq_extension(j, i, info);
  1555. return isl_change_none;
  1556. }
  1557. /* Given a basic set i with a constraint k that is adjacent to
  1558. * basic set j, check if we can wrap
  1559. * both the facet corresponding to k (if "wrap_facet" is set) and basic map j
  1560. * (always) around their ridges to include the other set.
  1561. * If so, replace the pair of basic sets by their union.
  1562. *
  1563. * All constraints of i (except k) are assumed to be valid or
  1564. * cut constraints for j.
  1565. * Wrapping the cut constraints to include basic map j may result
  1566. * in constraints that are no longer valid of basic map i
  1567. * we have to check that the resulting wrapping constraints are valid for i.
  1568. * If "wrap_facet" is not set, then all constraints of i (except k)
  1569. * are assumed to be valid for j.
  1570. * ____ _____
  1571. * / | / \
  1572. * / || / |
  1573. * \ || => \ |
  1574. * \ || \ |
  1575. * \___|| \____|
  1576. *
  1577. */
  1578. static enum isl_change can_wrap_in_facet(int i, int j, int k,
  1579. struct isl_coalesce_info *info, int wrap_facet)
  1580. {
  1581. enum isl_change change = isl_change_none;
  1582. struct isl_wraps wraps;
  1583. isl_ctx *ctx;
  1584. isl_mat *mat;
  1585. struct isl_set *set_i = NULL;
  1586. struct isl_set *set_j = NULL;
  1587. struct isl_vec *bound = NULL;
  1588. isl_size total = isl_basic_map_dim(info[i].bmap, isl_dim_all);
  1589. if (total < 0)
  1590. return isl_change_error;
  1591. set_i = set_from_updated_bmap(info[i].bmap, info[i].tab);
  1592. set_j = set_from_updated_bmap(info[j].bmap, info[j].tab);
  1593. ctx = isl_basic_map_get_ctx(info[i].bmap);
  1594. mat = isl_mat_alloc(ctx, 2 * (info[i].bmap->n_eq + info[j].bmap->n_eq) +
  1595. info[i].bmap->n_ineq + info[j].bmap->n_ineq,
  1596. 1 + total);
  1597. if (wraps_init(&wraps, mat, info, i, j) < 0)
  1598. goto error;
  1599. bound = isl_vec_alloc(ctx, 1 + total);
  1600. if (!set_i || !set_j || !bound)
  1601. goto error;
  1602. isl_seq_cpy(bound->el, info[i].bmap->ineq[k], 1 + total);
  1603. isl_int_add_ui(bound->el[0], bound->el[0], 1);
  1604. isl_seq_normalize(ctx, bound->el, 1 + total);
  1605. isl_seq_cpy(wraps.mat->row[0], bound->el, 1 + total);
  1606. wraps.mat->n_row = 1;
  1607. if (add_wraps(&wraps, &info[j], bound->el, set_i) < 0)
  1608. goto error;
  1609. if (wraps.failed)
  1610. goto unbounded;
  1611. if (wrap_facet) {
  1612. if (add_wraps_around_facet(&wraps, &info[i], k,
  1613. bound->el, set_j) < 0)
  1614. goto error;
  1615. if (wraps.failed)
  1616. goto unbounded;
  1617. }
  1618. change = fuse(i, j, info, wraps.mat, 0, 0);
  1619. unbounded:
  1620. wraps_free(&wraps);
  1621. isl_set_free(set_i);
  1622. isl_set_free(set_j);
  1623. isl_vec_free(bound);
  1624. return change;
  1625. error:
  1626. wraps_free(&wraps);
  1627. isl_vec_free(bound);
  1628. isl_set_free(set_i);
  1629. isl_set_free(set_j);
  1630. return isl_change_error;
  1631. }
  1632. /* Given a cut constraint t(x) >= 0 of basic map i, stored in row "w"
  1633. * of wrap.mat, replace it by its relaxed version t(x) + 1 >= 0, and
  1634. * add wrapping constraints to wrap.mat for all constraints
  1635. * of basic map j that bound the part of basic map j that sticks out
  1636. * of the cut constraint.
  1637. * "set_i" is the underlying set of basic map i.
  1638. * If any wrapping fails, then wraps->mat.n_row is reset to zero.
  1639. *
  1640. * In particular, we first intersect basic map j with t(x) + 1 = 0.
  1641. * If the result is empty, then t(x) >= 0 was actually a valid constraint
  1642. * (with respect to the integer points), so we add t(x) >= 0 instead.
  1643. * Otherwise, we wrap the constraints of basic map j that are not
  1644. * redundant in this intersection and that are not already valid
  1645. * for basic map i over basic map i.
  1646. * Note that it is sufficient to wrap the constraints to include
  1647. * basic map i, because we will only wrap the constraints that do
  1648. * not include basic map i already. The wrapped constraint will
  1649. * therefore be more relaxed compared to the original constraint.
  1650. * Since the original constraint is valid for basic map j, so is
  1651. * the wrapped constraint.
  1652. */
  1653. static isl_stat wrap_in_facet(struct isl_wraps *wraps, int w,
  1654. struct isl_coalesce_info *info_j, __isl_keep isl_set *set_i,
  1655. struct isl_tab_undo *snap)
  1656. {
  1657. isl_int_add_ui(wraps->mat->row[w][0], wraps->mat->row[w][0], 1);
  1658. if (isl_tab_add_eq(info_j->tab, wraps->mat->row[w]) < 0)
  1659. return isl_stat_error;
  1660. if (isl_tab_detect_redundant(info_j->tab) < 0)
  1661. return isl_stat_error;
  1662. if (info_j->tab->empty)
  1663. isl_int_sub_ui(wraps->mat->row[w][0], wraps->mat->row[w][0], 1);
  1664. else if (add_wraps(wraps, info_j, wraps->mat->row[w], set_i) < 0)
  1665. return isl_stat_error;
  1666. if (isl_tab_rollback(info_j->tab, snap) < 0)
  1667. return isl_stat_error;
  1668. return isl_stat_ok;
  1669. }
  1670. /* Given a pair of basic maps i and j such that j sticks out
  1671. * of i at n cut constraints, each time by at most one,
  1672. * try to compute wrapping constraints and replace the two
  1673. * basic maps by a single basic map.
  1674. * The other constraints of i are assumed to be valid for j.
  1675. * "set_i" is the underlying set of basic map i.
  1676. * "wraps" has been initialized to be of the right size.
  1677. *
  1678. * For each cut constraint t(x) >= 0 of i, we add the relaxed version
  1679. * t(x) + 1 >= 0, along with wrapping constraints for all constraints
  1680. * of basic map j that bound the part of basic map j that sticks out
  1681. * of the cut constraint.
  1682. *
  1683. * If any wrapping fails, i.e., if we cannot wrap to touch
  1684. * the union, then we give up.
  1685. * Otherwise, the pair of basic maps is replaced by their union.
  1686. */
  1687. static enum isl_change try_wrap_in_facets(int i, int j,
  1688. struct isl_coalesce_info *info, struct isl_wraps *wraps,
  1689. __isl_keep isl_set *set_i)
  1690. {
  1691. int k, l, w;
  1692. isl_size total;
  1693. struct isl_tab_undo *snap;
  1694. total = isl_basic_map_dim(info[i].bmap, isl_dim_all);
  1695. if (total < 0)
  1696. return isl_change_error;
  1697. snap = isl_tab_snap(info[j].tab);
  1698. for (k = 0; k < info[i].bmap->n_eq; ++k) {
  1699. for (l = 0; l < 2; ++l) {
  1700. if (info[i].eq[2 * k + l] != STATUS_CUT)
  1701. continue;
  1702. w = wraps->mat->n_row++;
  1703. if (l == 0)
  1704. isl_seq_neg(wraps->mat->row[w],
  1705. info[i].bmap->eq[k], 1 + total);
  1706. else
  1707. isl_seq_cpy(wraps->mat->row[w],
  1708. info[i].bmap->eq[k], 1 + total);
  1709. if (wrap_in_facet(wraps, w, &info[j], set_i, snap) < 0)
  1710. return isl_change_error;
  1711. if (wraps->failed)
  1712. return isl_change_none;
  1713. }
  1714. }
  1715. for (k = 0; k < info[i].bmap->n_ineq; ++k) {
  1716. if (info[i].ineq[k] != STATUS_CUT)
  1717. continue;
  1718. w = wraps->mat->n_row++;
  1719. isl_seq_cpy(wraps->mat->row[w],
  1720. info[i].bmap->ineq[k], 1 + total);
  1721. if (wrap_in_facet(wraps, w, &info[j], set_i, snap) < 0)
  1722. return isl_change_error;
  1723. if (wraps->failed)
  1724. return isl_change_none;
  1725. }
  1726. return fuse(i, j, info, wraps->mat, 0, 1);
  1727. }
  1728. /* Given a pair of basic maps i and j such that j sticks out
  1729. * of i at n cut constraints, each time by at most one,
  1730. * try to compute wrapping constraints and replace the two
  1731. * basic maps by a single basic map.
  1732. * The other constraints of i are assumed to be valid for j.
  1733. *
  1734. * The core computation is performed by try_wrap_in_facets.
  1735. * This function simply extracts an underlying set representation
  1736. * of basic map i and initializes the data structure for keeping
  1737. * track of wrapping constraints.
  1738. */
  1739. static enum isl_change wrap_in_facets(int i, int j, int n,
  1740. struct isl_coalesce_info *info)
  1741. {
  1742. enum isl_change change = isl_change_none;
  1743. struct isl_wraps wraps;
  1744. isl_ctx *ctx;
  1745. isl_mat *mat;
  1746. isl_set *set_i = NULL;
  1747. isl_size total = isl_basic_map_dim(info[i].bmap, isl_dim_all);
  1748. int max_wrap;
  1749. if (total < 0)
  1750. return isl_change_error;
  1751. if (isl_tab_extend_cons(info[j].tab, 1) < 0)
  1752. return isl_change_error;
  1753. max_wrap = 1 + 2 * info[j].bmap->n_eq + info[j].bmap->n_ineq;
  1754. max_wrap *= n;
  1755. set_i = set_from_updated_bmap(info[i].bmap, info[i].tab);
  1756. ctx = isl_basic_map_get_ctx(info[i].bmap);
  1757. mat = isl_mat_alloc(ctx, max_wrap, 1 + total);
  1758. if (wraps_init(&wraps, mat, info, i, j) < 0)
  1759. goto error;
  1760. if (!set_i)
  1761. goto error;
  1762. change = try_wrap_in_facets(i, j, info, &wraps, set_i);
  1763. wraps_free(&wraps);
  1764. isl_set_free(set_i);
  1765. return change;
  1766. error:
  1767. wraps_free(&wraps);
  1768. isl_set_free(set_i);
  1769. return isl_change_error;
  1770. }
  1771. /* Return the effect of inequality "ineq" on the tableau "tab",
  1772. * after relaxing the constant term of "ineq" by one.
  1773. */
  1774. static enum isl_ineq_type type_of_relaxed(struct isl_tab *tab, isl_int *ineq)
  1775. {
  1776. enum isl_ineq_type type;
  1777. isl_int_add_ui(ineq[0], ineq[0], 1);
  1778. type = isl_tab_ineq_type(tab, ineq);
  1779. isl_int_sub_ui(ineq[0], ineq[0], 1);
  1780. return type;
  1781. }
  1782. /* Given two basic sets i and j,
  1783. * check if relaxing all the cut constraints of i by one turns
  1784. * them into valid constraint for j and check if we can wrap in
  1785. * the bits that are sticking out.
  1786. * If so, replace the pair by their union.
  1787. *
  1788. * We first check if all relaxed cut inequalities of i are valid for j
  1789. * and then try to wrap in the intersections of the relaxed cut inequalities
  1790. * with j.
  1791. *
  1792. * During this wrapping, we consider the points of j that lie at a distance
  1793. * of exactly 1 from i. In particular, we ignore the points that lie in
  1794. * between this lower-dimensional space and the basic map i.
  1795. * We can therefore only apply this to integer maps.
  1796. * ____ _____
  1797. * / ___|_ / \
  1798. * / | | / |
  1799. * \ | | => \ |
  1800. * \|____| \ |
  1801. * \___| \____/
  1802. *
  1803. * _____ ______
  1804. * | ____|_ | \
  1805. * | | | | |
  1806. * | | | => | |
  1807. * |_| | | |
  1808. * |_____| \______|
  1809. *
  1810. * _______
  1811. * | |
  1812. * | |\ |
  1813. * | | \ |
  1814. * | | \ |
  1815. * | | \|
  1816. * | | \
  1817. * | |_____\
  1818. * | |
  1819. * |_______|
  1820. *
  1821. * Wrapping can fail if the result of wrapping one of the facets
  1822. * around its edges does not produce any new facet constraint.
  1823. * In particular, this happens when we try to wrap in unbounded sets.
  1824. *
  1825. * _______________________________________________________________________
  1826. * |
  1827. * | ___
  1828. * | | |
  1829. * |_| |_________________________________________________________________
  1830. * |___|
  1831. *
  1832. * The following is not an acceptable result of coalescing the above two
  1833. * sets as it includes extra integer points.
  1834. * _______________________________________________________________________
  1835. * |
  1836. * |
  1837. * |
  1838. * |
  1839. * \______________________________________________________________________
  1840. */
  1841. static enum isl_change can_wrap_in_set(int i, int j,
  1842. struct isl_coalesce_info *info)
  1843. {
  1844. int k, l;
  1845. int n;
  1846. isl_size total;
  1847. if (ISL_F_ISSET(info[i].bmap, ISL_BASIC_MAP_RATIONAL) ||
  1848. ISL_F_ISSET(info[j].bmap, ISL_BASIC_MAP_RATIONAL))
  1849. return isl_change_none;
  1850. n = count_eq(&info[i], STATUS_CUT) + count_ineq(&info[i], STATUS_CUT);
  1851. if (n == 0)
  1852. return isl_change_none;
  1853. total = isl_basic_map_dim(info[i].bmap, isl_dim_all);
  1854. if (total < 0)
  1855. return isl_change_error;
  1856. for (k = 0; k < info[i].bmap->n_eq; ++k) {
  1857. for (l = 0; l < 2; ++l) {
  1858. enum isl_ineq_type type;
  1859. if (info[i].eq[2 * k + l] != STATUS_CUT)
  1860. continue;
  1861. if (l == 0)
  1862. isl_seq_neg(info[i].bmap->eq[k],
  1863. info[i].bmap->eq[k], 1 + total);
  1864. type = type_of_relaxed(info[j].tab,
  1865. info[i].bmap->eq[k]);
  1866. if (l == 0)
  1867. isl_seq_neg(info[i].bmap->eq[k],
  1868. info[i].bmap->eq[k], 1 + total);
  1869. if (type == isl_ineq_error)
  1870. return isl_change_error;
  1871. if (type != isl_ineq_redundant)
  1872. return isl_change_none;
  1873. }
  1874. }
  1875. for (k = 0; k < info[i].bmap->n_ineq; ++k) {
  1876. enum isl_ineq_type type;
  1877. if (info[i].ineq[k] != STATUS_CUT)
  1878. continue;
  1879. type = type_of_relaxed(info[j].tab, info[i].bmap->ineq[k]);
  1880. if (type == isl_ineq_error)
  1881. return isl_change_error;
  1882. if (type != isl_ineq_redundant)
  1883. return isl_change_none;
  1884. }
  1885. return wrap_in_facets(i, j, n, info);
  1886. }
  1887. /* Check if either i or j has only cut constraints that can
  1888. * be used to wrap in (a facet of) the other basic set.
  1889. * if so, replace the pair by their union.
  1890. */
  1891. static enum isl_change check_wrap(int i, int j, struct isl_coalesce_info *info)
  1892. {
  1893. enum isl_change change = isl_change_none;
  1894. change = can_wrap_in_set(i, j, info);
  1895. if (change != isl_change_none)
  1896. return change;
  1897. change = can_wrap_in_set(j, i, info);
  1898. return change;
  1899. }
  1900. /* Check if all inequality constraints of "i" that cut "j" cease
  1901. * to be cut constraints if they are relaxed by one.
  1902. * If so, collect the cut constraints in "list".
  1903. * The caller is responsible for allocating "list".
  1904. */
  1905. static isl_bool all_cut_by_one(int i, int j, struct isl_coalesce_info *info,
  1906. int *list)
  1907. {
  1908. int l, n;
  1909. n = 0;
  1910. for (l = 0; l < info[i].bmap->n_ineq; ++l) {
  1911. enum isl_ineq_type type;
  1912. if (info[i].ineq[l] != STATUS_CUT)
  1913. continue;
  1914. type = type_of_relaxed(info[j].tab, info[i].bmap->ineq[l]);
  1915. if (type == isl_ineq_error)
  1916. return isl_bool_error;
  1917. if (type != isl_ineq_redundant)
  1918. return isl_bool_false;
  1919. list[n++] = l;
  1920. }
  1921. return isl_bool_true;
  1922. }
  1923. /* Given two basic maps such that "j" has at least one equality constraint
  1924. * that is adjacent to an inequality constraint of "i" and such that "i" has
  1925. * exactly one inequality constraint that is adjacent to an equality
  1926. * constraint of "j", check whether "i" can be extended to include "j" or
  1927. * whether "j" can be wrapped into "i".
  1928. * All remaining constraints of "i" and "j" are assumed to be valid
  1929. * or cut constraints of the other basic map.
  1930. * However, none of the equality constraints of "i" are cut constraints.
  1931. *
  1932. * If "i" has any "cut" inequality constraints, then check if relaxing
  1933. * each of them by one is sufficient for them to become valid.
  1934. * If so, check if the inequality constraint adjacent to an equality
  1935. * constraint of "j" along with all these cut constraints
  1936. * can be relaxed by one to contain exactly "j".
  1937. * Otherwise, or if this fails, check if "j" can be wrapped into "i".
  1938. */
  1939. static enum isl_change check_single_adj_eq(int i, int j,
  1940. struct isl_coalesce_info *info)
  1941. {
  1942. enum isl_change change = isl_change_none;
  1943. int k;
  1944. int n_cut;
  1945. int *relax;
  1946. isl_ctx *ctx;
  1947. isl_bool try_relax;
  1948. n_cut = count_ineq(&info[i], STATUS_CUT);
  1949. k = find_ineq(&info[i], STATUS_ADJ_EQ);
  1950. if (n_cut > 0) {
  1951. ctx = isl_basic_map_get_ctx(info[i].bmap);
  1952. relax = isl_calloc_array(ctx, int, 1 + n_cut);
  1953. if (!relax)
  1954. return isl_change_error;
  1955. relax[0] = k;
  1956. try_relax = all_cut_by_one(i, j, info, relax + 1);
  1957. if (try_relax < 0)
  1958. change = isl_change_error;
  1959. } else {
  1960. try_relax = isl_bool_true;
  1961. relax = &k;
  1962. }
  1963. if (try_relax && change == isl_change_none)
  1964. change = is_relaxed_extension(i, j, 1 + n_cut, relax, info);
  1965. if (n_cut > 0)
  1966. free(relax);
  1967. if (change != isl_change_none)
  1968. return change;
  1969. change = can_wrap_in_facet(i, j, k, info, n_cut > 0);
  1970. return change;
  1971. }
  1972. /* At least one of the basic maps has an equality that is adjacent
  1973. * to an inequality. Make sure that only one of the basic maps has
  1974. * such an equality and that the other basic map has exactly one
  1975. * inequality adjacent to an equality.
  1976. * If the other basic map does not have such an inequality, then
  1977. * check if all its constraints are either valid or cut constraints
  1978. * and, if so, try wrapping in the first map into the second.
  1979. * Otherwise, try to extend one basic map with the other or
  1980. * wrap one basic map in the other.
  1981. */
  1982. static enum isl_change check_adj_eq(int i, int j,
  1983. struct isl_coalesce_info *info)
  1984. {
  1985. if (any_eq(&info[i], STATUS_ADJ_INEQ) &&
  1986. any_eq(&info[j], STATUS_ADJ_INEQ))
  1987. /* ADJ EQ TOO MANY */
  1988. return isl_change_none;
  1989. if (any_eq(&info[i], STATUS_ADJ_INEQ))
  1990. return check_adj_eq(j, i, info);
  1991. /* j has an equality adjacent to an inequality in i */
  1992. if (count_ineq(&info[i], STATUS_ADJ_EQ) != 1) {
  1993. if (all_valid_or_cut(&info[i]))
  1994. return can_wrap_in_set(i, j, info);
  1995. return isl_change_none;
  1996. }
  1997. if (any_eq(&info[i], STATUS_CUT))
  1998. return isl_change_none;
  1999. if (any_ineq(&info[j], STATUS_ADJ_EQ) ||
  2000. any_ineq(&info[i], STATUS_ADJ_INEQ) ||
  2001. any_ineq(&info[j], STATUS_ADJ_INEQ))
  2002. /* ADJ EQ TOO MANY */
  2003. return isl_change_none;
  2004. return check_single_adj_eq(i, j, info);
  2005. }
  2006. /* Disjunct "j" lies on a hyperplane that is adjacent to disjunct "i".
  2007. * In particular, disjunct "i" has an inequality constraint that is adjacent
  2008. * to a (combination of) equality constraint(s) of disjunct "j",
  2009. * but disjunct "j" has no explicit equality constraint adjacent
  2010. * to an inequality constraint of disjunct "i".
  2011. *
  2012. * Disjunct "i" is already known not to have any equality constraints
  2013. * that are adjacent to an equality or inequality constraint.
  2014. * Check that, other than the inequality constraint mentioned above,
  2015. * all other constraints of disjunct "i" are valid for disjunct "j".
  2016. * If so, try and wrap in disjunct "j".
  2017. */
  2018. static enum isl_change check_ineq_adj_eq(int i, int j,
  2019. struct isl_coalesce_info *info)
  2020. {
  2021. int k;
  2022. if (any_eq(&info[i], STATUS_CUT))
  2023. return isl_change_none;
  2024. if (any_ineq(&info[i], STATUS_CUT))
  2025. return isl_change_none;
  2026. if (any_ineq(&info[i], STATUS_ADJ_INEQ))
  2027. return isl_change_none;
  2028. if (count_ineq(&info[i], STATUS_ADJ_EQ) != 1)
  2029. return isl_change_none;
  2030. k = find_ineq(&info[i], STATUS_ADJ_EQ);
  2031. return can_wrap_in_facet(i, j, k, info, 0);
  2032. }
  2033. /* The two basic maps lie on adjacent hyperplanes. In particular,
  2034. * basic map "i" has an equality that lies parallel to basic map "j".
  2035. * Check if we can wrap the facets around the parallel hyperplanes
  2036. * to include the other set.
  2037. *
  2038. * We perform basically the same operations as can_wrap_in_facet,
  2039. * except that we don't need to select a facet of one of the sets.
  2040. * _
  2041. * \\ \\
  2042. * \\ => \\
  2043. * \ \|
  2044. *
  2045. * If there is more than one equality of "i" adjacent to an equality of "j",
  2046. * then the result will satisfy one or more equalities that are a linear
  2047. * combination of these equalities. These will be encoded as pairs
  2048. * of inequalities in the wrapping constraints and need to be made
  2049. * explicit.
  2050. */
  2051. static enum isl_change check_eq_adj_eq(int i, int j,
  2052. struct isl_coalesce_info *info)
  2053. {
  2054. int k;
  2055. enum isl_change change = isl_change_none;
  2056. int detect_equalities = 0;
  2057. struct isl_wraps wraps;
  2058. isl_ctx *ctx;
  2059. isl_mat *mat;
  2060. struct isl_set *set_i = NULL;
  2061. struct isl_set *set_j = NULL;
  2062. struct isl_vec *bound = NULL;
  2063. isl_size total = isl_basic_map_dim(info[i].bmap, isl_dim_all);
  2064. if (total < 0)
  2065. return isl_change_error;
  2066. if (count_eq(&info[i], STATUS_ADJ_EQ) != 1)
  2067. detect_equalities = 1;
  2068. k = find_eq(&info[i], STATUS_ADJ_EQ);
  2069. set_i = set_from_updated_bmap(info[i].bmap, info[i].tab);
  2070. set_j = set_from_updated_bmap(info[j].bmap, info[j].tab);
  2071. ctx = isl_basic_map_get_ctx(info[i].bmap);
  2072. mat = isl_mat_alloc(ctx, 2 * (info[i].bmap->n_eq + info[j].bmap->n_eq) +
  2073. info[i].bmap->n_ineq + info[j].bmap->n_ineq,
  2074. 1 + total);
  2075. if (wraps_init(&wraps, mat, info, i, j) < 0)
  2076. goto error;
  2077. bound = isl_vec_alloc(ctx, 1 + total);
  2078. if (!set_i || !set_j || !bound)
  2079. goto error;
  2080. if (k % 2 == 0)
  2081. isl_seq_neg(bound->el, info[i].bmap->eq[k / 2], 1 + total);
  2082. else
  2083. isl_seq_cpy(bound->el, info[i].bmap->eq[k / 2], 1 + total);
  2084. isl_int_add_ui(bound->el[0], bound->el[0], 1);
  2085. isl_seq_cpy(wraps.mat->row[0], bound->el, 1 + total);
  2086. wraps.mat->n_row = 1;
  2087. if (add_wraps(&wraps, &info[j], bound->el, set_i) < 0)
  2088. goto error;
  2089. if (wraps.failed)
  2090. goto unbounded;
  2091. isl_int_sub_ui(bound->el[0], bound->el[0], 1);
  2092. isl_seq_neg(bound->el, bound->el, 1 + total);
  2093. isl_seq_cpy(wraps.mat->row[wraps.mat->n_row], bound->el, 1 + total);
  2094. wraps.mat->n_row++;
  2095. if (add_wraps(&wraps, &info[i], bound->el, set_j) < 0)
  2096. goto error;
  2097. if (wraps.failed)
  2098. goto unbounded;
  2099. change = fuse(i, j, info, wraps.mat, detect_equalities, 0);
  2100. if (0) {
  2101. error: change = isl_change_error;
  2102. }
  2103. unbounded:
  2104. wraps_free(&wraps);
  2105. isl_set_free(set_i);
  2106. isl_set_free(set_j);
  2107. isl_vec_free(bound);
  2108. return change;
  2109. }
  2110. /* Initialize the "eq" and "ineq" fields of "info".
  2111. */
  2112. static void init_status(struct isl_coalesce_info *info)
  2113. {
  2114. info->eq = info->ineq = NULL;
  2115. }
  2116. /* Set info->eq to the positions of the equalities of info->bmap
  2117. * with respect to the basic map represented by "tab".
  2118. * If info->eq has already been computed, then do not compute it again.
  2119. */
  2120. static void set_eq_status_in(struct isl_coalesce_info *info,
  2121. struct isl_tab *tab)
  2122. {
  2123. if (info->eq)
  2124. return;
  2125. info->eq = eq_status_in(info->bmap, tab);
  2126. }
  2127. /* Set info->ineq to the positions of the inequalities of info->bmap
  2128. * with respect to the basic map represented by "tab".
  2129. * If info->ineq has already been computed, then do not compute it again.
  2130. */
  2131. static void set_ineq_status_in(struct isl_coalesce_info *info,
  2132. struct isl_tab *tab)
  2133. {
  2134. if (info->ineq)
  2135. return;
  2136. info->ineq = ineq_status_in(info->bmap, info->tab, tab);
  2137. }
  2138. /* Free the memory allocated by the "eq" and "ineq" fields of "info".
  2139. * This function assumes that init_status has been called on "info" first,
  2140. * after which the "eq" and "ineq" fields may or may not have been
  2141. * assigned a newly allocated array.
  2142. */
  2143. static void clear_status(struct isl_coalesce_info *info)
  2144. {
  2145. free(info->eq);
  2146. free(info->ineq);
  2147. }
  2148. /* Are all inequality constraints of the basic map represented by "info"
  2149. * valid for the other basic map, except for a single constraint
  2150. * that is adjacent to an inequality constraint of the other basic map?
  2151. */
  2152. static int all_ineq_valid_or_single_adj_ineq(struct isl_coalesce_info *info)
  2153. {
  2154. int i;
  2155. int k = -1;
  2156. for (i = 0; i < info->bmap->n_ineq; ++i) {
  2157. if (info->ineq[i] == STATUS_REDUNDANT)
  2158. continue;
  2159. if (info->ineq[i] == STATUS_VALID)
  2160. continue;
  2161. if (info->ineq[i] != STATUS_ADJ_INEQ)
  2162. return 0;
  2163. if (k != -1)
  2164. return 0;
  2165. k = i;
  2166. }
  2167. return k != -1;
  2168. }
  2169. /* Basic map "i" has one or more equality constraints that separate it
  2170. * from basic map "j". Check if it happens to be an extension
  2171. * of basic map "j".
  2172. * In particular, check that all constraints of "j" are valid for "i",
  2173. * except for one inequality constraint that is adjacent
  2174. * to an inequality constraints of "i".
  2175. * If so, check for "i" being an extension of "j" by calling
  2176. * is_adj_ineq_extension.
  2177. *
  2178. * Clean up the memory allocated for keeping track of the status
  2179. * of the constraints before returning.
  2180. */
  2181. static enum isl_change separating_equality(int i, int j,
  2182. struct isl_coalesce_info *info)
  2183. {
  2184. enum isl_change change = isl_change_none;
  2185. if (all(info[j].eq, 2 * info[j].bmap->n_eq, STATUS_VALID) &&
  2186. all_ineq_valid_or_single_adj_ineq(&info[j]))
  2187. change = is_adj_ineq_extension(j, i, info);
  2188. clear_status(&info[i]);
  2189. clear_status(&info[j]);
  2190. return change;
  2191. }
  2192. /* Check if the union of the given pair of basic maps
  2193. * can be represented by a single basic map.
  2194. * If so, replace the pair by the single basic map and return
  2195. * isl_change_drop_first, isl_change_drop_second or isl_change_fuse.
  2196. * Otherwise, return isl_change_none.
  2197. * The two basic maps are assumed to live in the same local space.
  2198. * The "eq" and "ineq" fields of info[i] and info[j] are assumed
  2199. * to have been initialized by the caller, either to NULL or
  2200. * to valid information.
  2201. *
  2202. * We first check the effect of each constraint of one basic map
  2203. * on the other basic map.
  2204. * The constraint may be
  2205. * redundant the constraint is redundant in its own
  2206. * basic map and should be ignore and removed
  2207. * in the end
  2208. * valid all (integer) points of the other basic map
  2209. * satisfy the constraint
  2210. * separate no (integer) point of the other basic map
  2211. * satisfies the constraint
  2212. * cut some but not all points of the other basic map
  2213. * satisfy the constraint
  2214. * adj_eq the given constraint is adjacent (on the outside)
  2215. * to an equality of the other basic map
  2216. * adj_ineq the given constraint is adjacent (on the outside)
  2217. * to an inequality of the other basic map
  2218. *
  2219. * We consider seven cases in which we can replace the pair by a single
  2220. * basic map. We ignore all "redundant" constraints.
  2221. *
  2222. * 1. all constraints of one basic map are valid
  2223. * => the other basic map is a subset and can be removed
  2224. *
  2225. * 2. all constraints of both basic maps are either "valid" or "cut"
  2226. * and the facets corresponding to the "cut" constraints
  2227. * of one of the basic maps lies entirely inside the other basic map
  2228. * => the pair can be replaced by a basic map consisting
  2229. * of the valid constraints in both basic maps
  2230. *
  2231. * 3. there is a single pair of adjacent inequalities
  2232. * (all other constraints are "valid")
  2233. * => the pair can be replaced by a basic map consisting
  2234. * of the valid constraints in both basic maps
  2235. *
  2236. * 4. one basic map has a single adjacent inequality, while the other
  2237. * constraints are "valid". The other basic map has some
  2238. * "cut" constraints, but replacing the adjacent inequality by
  2239. * its opposite and adding the valid constraints of the other
  2240. * basic map results in a subset of the other basic map
  2241. * => the pair can be replaced by a basic map consisting
  2242. * of the valid constraints in both basic maps
  2243. *
  2244. * 5. there is a single adjacent pair of an inequality and an equality,
  2245. * the other constraints of the basic map containing the inequality are
  2246. * "valid". Moreover, if the inequality the basic map is relaxed
  2247. * and then turned into an equality, then resulting facet lies
  2248. * entirely inside the other basic map
  2249. * => the pair can be replaced by the basic map containing
  2250. * the inequality, with the inequality relaxed.
  2251. *
  2252. * 6. there is a single inequality adjacent to an equality,
  2253. * the other constraints of the basic map containing the inequality are
  2254. * "valid". Moreover, the facets corresponding to both
  2255. * the inequality and the equality can be wrapped around their
  2256. * ridges to include the other basic map
  2257. * => the pair can be replaced by a basic map consisting
  2258. * of the valid constraints in both basic maps together
  2259. * with all wrapping constraints
  2260. *
  2261. * 7. one of the basic maps extends beyond the other by at most one.
  2262. * Moreover, the facets corresponding to the cut constraints and
  2263. * the pieces of the other basic map at offset one from these cut
  2264. * constraints can be wrapped around their ridges to include
  2265. * the union of the two basic maps
  2266. * => the pair can be replaced by a basic map consisting
  2267. * of the valid constraints in both basic maps together
  2268. * with all wrapping constraints
  2269. *
  2270. * 8. the two basic maps live in adjacent hyperplanes. In principle
  2271. * such sets can always be combined through wrapping, but we impose
  2272. * that there is only one such pair, to avoid overeager coalescing.
  2273. *
  2274. * Throughout the computation, we maintain a collection of tableaus
  2275. * corresponding to the basic maps. When the basic maps are dropped
  2276. * or combined, the tableaus are modified accordingly.
  2277. */
  2278. static enum isl_change coalesce_local_pair_reuse(int i, int j,
  2279. struct isl_coalesce_info *info)
  2280. {
  2281. enum isl_change change = isl_change_none;
  2282. set_ineq_status_in(&info[i], info[j].tab);
  2283. if (info[i].bmap->n_ineq && !info[i].ineq)
  2284. goto error;
  2285. if (any_ineq(&info[i], STATUS_ERROR))
  2286. goto error;
  2287. if (any_ineq(&info[i], STATUS_SEPARATE))
  2288. goto done;
  2289. set_ineq_status_in(&info[j], info[i].tab);
  2290. if (info[j].bmap->n_ineq && !info[j].ineq)
  2291. goto error;
  2292. if (any_ineq(&info[j], STATUS_ERROR))
  2293. goto error;
  2294. if (any_ineq(&info[j], STATUS_SEPARATE))
  2295. goto done;
  2296. set_eq_status_in(&info[i], info[j].tab);
  2297. if (info[i].bmap->n_eq && !info[i].eq)
  2298. goto error;
  2299. if (any_eq(&info[i], STATUS_ERROR))
  2300. goto error;
  2301. set_eq_status_in(&info[j], info[i].tab);
  2302. if (info[j].bmap->n_eq && !info[j].eq)
  2303. goto error;
  2304. if (any_eq(&info[j], STATUS_ERROR))
  2305. goto error;
  2306. if (any_eq(&info[i], STATUS_SEPARATE))
  2307. return separating_equality(i, j, info);
  2308. if (any_eq(&info[j], STATUS_SEPARATE))
  2309. return separating_equality(j, i, info);
  2310. if (all(info[i].eq, 2 * info[i].bmap->n_eq, STATUS_VALID) &&
  2311. all(info[i].ineq, info[i].bmap->n_ineq, STATUS_VALID)) {
  2312. drop(&info[j]);
  2313. change = isl_change_drop_second;
  2314. } else if (all(info[j].eq, 2 * info[j].bmap->n_eq, STATUS_VALID) &&
  2315. all(info[j].ineq, info[j].bmap->n_ineq, STATUS_VALID)) {
  2316. drop(&info[i]);
  2317. change = isl_change_drop_first;
  2318. } else if (any_eq(&info[i], STATUS_ADJ_EQ)) {
  2319. change = check_eq_adj_eq(i, j, info);
  2320. } else if (any_eq(&info[j], STATUS_ADJ_EQ)) {
  2321. change = check_eq_adj_eq(j, i, info);
  2322. } else if (any_eq(&info[i], STATUS_ADJ_INEQ) ||
  2323. any_eq(&info[j], STATUS_ADJ_INEQ)) {
  2324. change = check_adj_eq(i, j, info);
  2325. } else if (any_ineq(&info[i], STATUS_ADJ_EQ)) {
  2326. change = check_ineq_adj_eq(i, j, info);
  2327. } else if (any_ineq(&info[j], STATUS_ADJ_EQ)) {
  2328. change = check_ineq_adj_eq(j, i, info);
  2329. } else if (any_ineq(&info[i], STATUS_ADJ_INEQ) ||
  2330. any_ineq(&info[j], STATUS_ADJ_INEQ)) {
  2331. change = check_adj_ineq(i, j, info);
  2332. } else {
  2333. if (!any_eq(&info[i], STATUS_CUT) &&
  2334. !any_eq(&info[j], STATUS_CUT))
  2335. change = check_facets(i, j, info);
  2336. if (change == isl_change_none)
  2337. change = check_wrap(i, j, info);
  2338. }
  2339. done:
  2340. clear_status(&info[i]);
  2341. clear_status(&info[j]);
  2342. return change;
  2343. error:
  2344. clear_status(&info[i]);
  2345. clear_status(&info[j]);
  2346. return isl_change_error;
  2347. }
  2348. /* Check if the union of the given pair of basic maps
  2349. * can be represented by a single basic map.
  2350. * If so, replace the pair by the single basic map and return
  2351. * isl_change_drop_first, isl_change_drop_second or isl_change_fuse.
  2352. * Otherwise, return isl_change_none.
  2353. * The two basic maps are assumed to live in the same local space.
  2354. */
  2355. static enum isl_change coalesce_local_pair(int i, int j,
  2356. struct isl_coalesce_info *info)
  2357. {
  2358. init_status(&info[i]);
  2359. init_status(&info[j]);
  2360. return coalesce_local_pair_reuse(i, j, info);
  2361. }
  2362. /* Shift the integer division at position "div" of the basic map
  2363. * represented by "info" by "shift".
  2364. *
  2365. * That is, if the integer division has the form
  2366. *
  2367. * floor(f(x)/d)
  2368. *
  2369. * then replace it by
  2370. *
  2371. * floor((f(x) + shift * d)/d) - shift
  2372. */
  2373. static isl_stat shift_div(struct isl_coalesce_info *info, int div,
  2374. isl_int shift)
  2375. {
  2376. isl_size total, n_div;
  2377. info->bmap = isl_basic_map_shift_div(info->bmap, div, 0, shift);
  2378. if (!info->bmap)
  2379. return isl_stat_error;
  2380. total = isl_basic_map_dim(info->bmap, isl_dim_all);
  2381. n_div = isl_basic_map_dim(info->bmap, isl_dim_div);
  2382. if (total < 0 || n_div < 0)
  2383. return isl_stat_error;
  2384. total -= n_div;
  2385. if (isl_tab_shift_var(info->tab, total + div, shift) < 0)
  2386. return isl_stat_error;
  2387. return isl_stat_ok;
  2388. }
  2389. /* If the integer division at position "div" is defined by an equality,
  2390. * i.e., a stride constraint, then change the integer division expression
  2391. * to have a constant term equal to zero.
  2392. *
  2393. * Let the equality constraint be
  2394. *
  2395. * c + f + m a = 0
  2396. *
  2397. * The integer division expression is then typically of the form
  2398. *
  2399. * a = floor((-f - c')/m)
  2400. *
  2401. * The integer division is first shifted by t = floor(c/m),
  2402. * turning the equality constraint into
  2403. *
  2404. * c - m floor(c/m) + f + m a' = 0
  2405. *
  2406. * i.e.,
  2407. *
  2408. * (c mod m) + f + m a' = 0
  2409. *
  2410. * That is,
  2411. *
  2412. * a' = (-f - (c mod m))/m = floor((-f)/m)
  2413. *
  2414. * because a' is an integer and 0 <= (c mod m) < m.
  2415. * The constant term of a' can therefore be zeroed out,
  2416. * but only if the integer division expression is of the expected form.
  2417. */
  2418. static isl_stat normalize_stride_div(struct isl_coalesce_info *info, int div)
  2419. {
  2420. isl_bool defined, valid;
  2421. isl_stat r;
  2422. isl_constraint *c;
  2423. isl_int shift, stride;
  2424. defined = isl_basic_map_has_defining_equality(info->bmap, isl_dim_div,
  2425. div, &c);
  2426. if (defined < 0)
  2427. return isl_stat_error;
  2428. if (!defined)
  2429. return isl_stat_ok;
  2430. if (!c)
  2431. return isl_stat_error;
  2432. valid = isl_constraint_is_div_equality(c, div);
  2433. isl_int_init(shift);
  2434. isl_int_init(stride);
  2435. isl_constraint_get_constant(c, &shift);
  2436. isl_constraint_get_coefficient(c, isl_dim_div, div, &stride);
  2437. isl_int_fdiv_q(shift, shift, stride);
  2438. r = shift_div(info, div, shift);
  2439. isl_int_clear(stride);
  2440. isl_int_clear(shift);
  2441. isl_constraint_free(c);
  2442. if (r < 0 || valid < 0)
  2443. return isl_stat_error;
  2444. if (!valid)
  2445. return isl_stat_ok;
  2446. info->bmap = isl_basic_map_set_div_expr_constant_num_si_inplace(
  2447. info->bmap, div, 0);
  2448. if (!info->bmap)
  2449. return isl_stat_error;
  2450. return isl_stat_ok;
  2451. }
  2452. /* The basic maps represented by "info1" and "info2" are known
  2453. * to have the same number of integer divisions.
  2454. * Check if pairs of integer divisions are equal to each other
  2455. * despite the fact that they differ by a rational constant.
  2456. *
  2457. * In particular, look for any pair of integer divisions that
  2458. * only differ in their constant terms.
  2459. * If either of these integer divisions is defined
  2460. * by stride constraints, then modify it to have a zero constant term.
  2461. * If both are defined by stride constraints then in the end they will have
  2462. * the same (zero) constant term.
  2463. */
  2464. static isl_stat harmonize_stride_divs(struct isl_coalesce_info *info1,
  2465. struct isl_coalesce_info *info2)
  2466. {
  2467. int i;
  2468. isl_size n;
  2469. n = isl_basic_map_dim(info1->bmap, isl_dim_div);
  2470. if (n < 0)
  2471. return isl_stat_error;
  2472. for (i = 0; i < n; ++i) {
  2473. isl_bool known, harmonize;
  2474. known = isl_basic_map_div_is_known(info1->bmap, i);
  2475. if (known >= 0 && known)
  2476. known = isl_basic_map_div_is_known(info2->bmap, i);
  2477. if (known < 0)
  2478. return isl_stat_error;
  2479. if (!known)
  2480. continue;
  2481. harmonize = isl_basic_map_equal_div_expr_except_constant(
  2482. info1->bmap, i, info2->bmap, i);
  2483. if (harmonize < 0)
  2484. return isl_stat_error;
  2485. if (!harmonize)
  2486. continue;
  2487. if (normalize_stride_div(info1, i) < 0)
  2488. return isl_stat_error;
  2489. if (normalize_stride_div(info2, i) < 0)
  2490. return isl_stat_error;
  2491. }
  2492. return isl_stat_ok;
  2493. }
  2494. /* If "shift" is an integer constant, then shift the integer division
  2495. * at position "div" of the basic map represented by "info" by "shift".
  2496. * If "shift" is not an integer constant, then do nothing.
  2497. * If "shift" is equal to zero, then no shift needs to be performed either.
  2498. *
  2499. * That is, if the integer division has the form
  2500. *
  2501. * floor(f(x)/d)
  2502. *
  2503. * then replace it by
  2504. *
  2505. * floor((f(x) + shift * d)/d) - shift
  2506. */
  2507. static isl_stat shift_if_cst_int(struct isl_coalesce_info *info, int div,
  2508. __isl_keep isl_aff *shift)
  2509. {
  2510. isl_bool cst;
  2511. isl_stat r;
  2512. isl_int d;
  2513. isl_val *c;
  2514. cst = isl_aff_is_cst(shift);
  2515. if (cst < 0 || !cst)
  2516. return cst < 0 ? isl_stat_error : isl_stat_ok;
  2517. c = isl_aff_get_constant_val(shift);
  2518. cst = isl_val_is_int(c);
  2519. if (cst >= 0 && cst)
  2520. cst = isl_bool_not(isl_val_is_zero(c));
  2521. if (cst < 0 || !cst) {
  2522. isl_val_free(c);
  2523. return cst < 0 ? isl_stat_error : isl_stat_ok;
  2524. }
  2525. isl_int_init(d);
  2526. r = isl_val_get_num_isl_int(c, &d);
  2527. if (r >= 0)
  2528. r = shift_div(info, div, d);
  2529. isl_int_clear(d);
  2530. isl_val_free(c);
  2531. return r;
  2532. }
  2533. /* Check if some of the divs in the basic map represented by "info1"
  2534. * are shifts of the corresponding divs in the basic map represented
  2535. * by "info2", taking into account the equality constraints "eq1" of "info1"
  2536. * and "eq2" of "info2". If so, align them with those of "info2".
  2537. * "info1" and "info2" are assumed to have the same number
  2538. * of integer divisions.
  2539. *
  2540. * An integer division is considered to be a shift of another integer
  2541. * division if, after simplification with respect to the equality
  2542. * constraints of the other basic map, one is equal to the other
  2543. * plus a constant.
  2544. *
  2545. * In particular, for each pair of integer divisions, if both are known,
  2546. * have the same denominator and are not already equal to each other,
  2547. * simplify each with respect to the equality constraints
  2548. * of the other basic map. If the difference is an integer constant,
  2549. * then move this difference outside.
  2550. * That is, if, after simplification, one integer division is of the form
  2551. *
  2552. * floor((f(x) + c_1)/d)
  2553. *
  2554. * while the other is of the form
  2555. *
  2556. * floor((f(x) + c_2)/d)
  2557. *
  2558. * and n = (c_2 - c_1)/d is an integer, then replace the first
  2559. * integer division by
  2560. *
  2561. * floor((f_1(x) + c_1 + n * d)/d) - n,
  2562. *
  2563. * where floor((f_1(x) + c_1 + n * d)/d) = floor((f2(x) + c_2)/d)
  2564. * after simplification with respect to the equality constraints.
  2565. */
  2566. static isl_stat harmonize_divs_with_hulls(struct isl_coalesce_info *info1,
  2567. struct isl_coalesce_info *info2, __isl_keep isl_basic_set *eq1,
  2568. __isl_keep isl_basic_set *eq2)
  2569. {
  2570. int i;
  2571. isl_size total;
  2572. isl_local_space *ls1, *ls2;
  2573. total = isl_basic_map_dim(info1->bmap, isl_dim_all);
  2574. if (total < 0)
  2575. return isl_stat_error;
  2576. ls1 = isl_local_space_wrap(isl_basic_map_get_local_space(info1->bmap));
  2577. ls2 = isl_local_space_wrap(isl_basic_map_get_local_space(info2->bmap));
  2578. for (i = 0; i < info1->bmap->n_div; ++i) {
  2579. isl_stat r;
  2580. isl_aff *div1, *div2;
  2581. if (!isl_local_space_div_is_known(ls1, i) ||
  2582. !isl_local_space_div_is_known(ls2, i))
  2583. continue;
  2584. if (isl_int_ne(info1->bmap->div[i][0], info2->bmap->div[i][0]))
  2585. continue;
  2586. if (isl_seq_eq(info1->bmap->div[i] + 1,
  2587. info2->bmap->div[i] + 1, 1 + total))
  2588. continue;
  2589. div1 = isl_local_space_get_div(ls1, i);
  2590. div2 = isl_local_space_get_div(ls2, i);
  2591. div1 = isl_aff_substitute_equalities(div1,
  2592. isl_basic_set_copy(eq2));
  2593. div2 = isl_aff_substitute_equalities(div2,
  2594. isl_basic_set_copy(eq1));
  2595. div2 = isl_aff_sub(div2, div1);
  2596. r = shift_if_cst_int(info1, i, div2);
  2597. isl_aff_free(div2);
  2598. if (r < 0)
  2599. break;
  2600. }
  2601. isl_local_space_free(ls1);
  2602. isl_local_space_free(ls2);
  2603. if (i < info1->bmap->n_div)
  2604. return isl_stat_error;
  2605. return isl_stat_ok;
  2606. }
  2607. /* Check if some of the divs in the basic map represented by "info1"
  2608. * are shifts of the corresponding divs in the basic map represented
  2609. * by "info2". If so, align them with those of "info2".
  2610. * Only do this if "info1" and "info2" have the same number
  2611. * of integer divisions.
  2612. *
  2613. * An integer division is considered to be a shift of another integer
  2614. * division if, after simplification with respect to the equality
  2615. * constraints of the other basic map, one is equal to the other
  2616. * plus a constant.
  2617. *
  2618. * First check if pairs of integer divisions are equal to each other
  2619. * despite the fact that they differ by a rational constant.
  2620. * If so, try and arrange for them to have the same constant term.
  2621. *
  2622. * Then, extract the equality constraints and continue with
  2623. * harmonize_divs_with_hulls.
  2624. *
  2625. * If the equality constraints of both basic maps are the same,
  2626. * then there is no need to perform any shifting since
  2627. * the coefficients of the integer divisions should have been
  2628. * reduced in the same way.
  2629. */
  2630. static isl_stat harmonize_divs(struct isl_coalesce_info *info1,
  2631. struct isl_coalesce_info *info2)
  2632. {
  2633. isl_bool equal;
  2634. isl_basic_map *bmap1, *bmap2;
  2635. isl_basic_set *eq1, *eq2;
  2636. isl_stat r;
  2637. if (!info1->bmap || !info2->bmap)
  2638. return isl_stat_error;
  2639. if (info1->bmap->n_div != info2->bmap->n_div)
  2640. return isl_stat_ok;
  2641. if (info1->bmap->n_div == 0)
  2642. return isl_stat_ok;
  2643. if (harmonize_stride_divs(info1, info2) < 0)
  2644. return isl_stat_error;
  2645. bmap1 = isl_basic_map_copy(info1->bmap);
  2646. bmap2 = isl_basic_map_copy(info2->bmap);
  2647. eq1 = isl_basic_map_wrap(isl_basic_map_plain_affine_hull(bmap1));
  2648. eq2 = isl_basic_map_wrap(isl_basic_map_plain_affine_hull(bmap2));
  2649. equal = isl_basic_set_plain_is_equal(eq1, eq2);
  2650. if (equal < 0)
  2651. r = isl_stat_error;
  2652. else if (equal)
  2653. r = isl_stat_ok;
  2654. else
  2655. r = harmonize_divs_with_hulls(info1, info2, eq1, eq2);
  2656. isl_basic_set_free(eq1);
  2657. isl_basic_set_free(eq2);
  2658. return r;
  2659. }
  2660. /* Do the two basic maps live in the same local space, i.e.,
  2661. * do they have the same (known) divs?
  2662. * If either basic map has any unknown divs, then we can only assume
  2663. * that they do not live in the same local space.
  2664. */
  2665. static isl_bool same_divs(__isl_keep isl_basic_map *bmap1,
  2666. __isl_keep isl_basic_map *bmap2)
  2667. {
  2668. int i;
  2669. isl_bool known;
  2670. isl_size total;
  2671. if (!bmap1 || !bmap2)
  2672. return isl_bool_error;
  2673. if (bmap1->n_div != bmap2->n_div)
  2674. return isl_bool_false;
  2675. if (bmap1->n_div == 0)
  2676. return isl_bool_true;
  2677. known = isl_basic_map_divs_known(bmap1);
  2678. if (known < 0 || !known)
  2679. return known;
  2680. known = isl_basic_map_divs_known(bmap2);
  2681. if (known < 0 || !known)
  2682. return known;
  2683. total = isl_basic_map_dim(bmap1, isl_dim_all);
  2684. if (total < 0)
  2685. return isl_bool_error;
  2686. for (i = 0; i < bmap1->n_div; ++i)
  2687. if (!isl_seq_eq(bmap1->div[i], bmap2->div[i], 2 + total))
  2688. return isl_bool_false;
  2689. return isl_bool_true;
  2690. }
  2691. /* Assuming that "tab" contains the equality constraints and
  2692. * the initial inequality constraints of "bmap", copy the remaining
  2693. * inequality constraints of "bmap" to "Tab".
  2694. */
  2695. static isl_stat copy_ineq(struct isl_tab *tab, __isl_keep isl_basic_map *bmap)
  2696. {
  2697. int i, n_ineq;
  2698. if (!bmap)
  2699. return isl_stat_error;
  2700. n_ineq = tab->n_con - tab->n_eq;
  2701. for (i = n_ineq; i < bmap->n_ineq; ++i)
  2702. if (isl_tab_add_ineq(tab, bmap->ineq[i]) < 0)
  2703. return isl_stat_error;
  2704. return isl_stat_ok;
  2705. }
  2706. /* Description of an integer division that is added
  2707. * during an expansion.
  2708. * "pos" is the position of the corresponding variable.
  2709. * "cst" indicates whether this integer division has a fixed value.
  2710. * "val" contains the fixed value, if the value is fixed.
  2711. */
  2712. struct isl_expanded {
  2713. int pos;
  2714. isl_bool cst;
  2715. isl_int val;
  2716. };
  2717. /* For each of the "n" integer division variables "expanded",
  2718. * if the variable has a fixed value, then add two inequality
  2719. * constraints expressing the fixed value.
  2720. * Otherwise, add the corresponding div constraints.
  2721. * The caller is responsible for removing the div constraints
  2722. * that it added for all these "n" integer divisions.
  2723. *
  2724. * The div constraints and the pair of inequality constraints
  2725. * forcing the fixed value cannot both be added for a given variable
  2726. * as the combination may render some of the original constraints redundant.
  2727. * These would then be ignored during the coalescing detection,
  2728. * while they could remain in the fused result.
  2729. *
  2730. * The two added inequality constraints are
  2731. *
  2732. * -a + v >= 0
  2733. * a - v >= 0
  2734. *
  2735. * with "a" the variable and "v" its fixed value.
  2736. * The facet corresponding to one of these two constraints is selected
  2737. * in the tableau to ensure that the pair of inequality constraints
  2738. * is treated as an equality constraint.
  2739. *
  2740. * The information in info->ineq is thrown away because it was
  2741. * computed in terms of div constraints, while some of those
  2742. * have now been replaced by these pairs of inequality constraints.
  2743. */
  2744. static isl_stat fix_constant_divs(struct isl_coalesce_info *info,
  2745. int n, struct isl_expanded *expanded)
  2746. {
  2747. unsigned o_div;
  2748. int i;
  2749. isl_vec *ineq;
  2750. o_div = isl_basic_map_offset(info->bmap, isl_dim_div) - 1;
  2751. ineq = isl_vec_alloc(isl_tab_get_ctx(info->tab), 1 + info->tab->n_var);
  2752. if (!ineq)
  2753. return isl_stat_error;
  2754. isl_seq_clr(ineq->el + 1, info->tab->n_var);
  2755. for (i = 0; i < n; ++i) {
  2756. if (!expanded[i].cst) {
  2757. info->bmap = isl_basic_map_extend_constraints(
  2758. info->bmap, 0, 2);
  2759. info->bmap = isl_basic_map_add_div_constraints(
  2760. info->bmap, expanded[i].pos - o_div);
  2761. } else {
  2762. isl_int_set_si(ineq->el[1 + expanded[i].pos], -1);
  2763. isl_int_set(ineq->el[0], expanded[i].val);
  2764. info->bmap = isl_basic_map_add_ineq(info->bmap,
  2765. ineq->el);
  2766. isl_int_set_si(ineq->el[1 + expanded[i].pos], 1);
  2767. isl_int_neg(ineq->el[0], expanded[i].val);
  2768. info->bmap = isl_basic_map_add_ineq(info->bmap,
  2769. ineq->el);
  2770. isl_int_set_si(ineq->el[1 + expanded[i].pos], 0);
  2771. }
  2772. if (copy_ineq(info->tab, info->bmap) < 0)
  2773. break;
  2774. if (expanded[i].cst &&
  2775. isl_tab_select_facet(info->tab, info->tab->n_con - 1) < 0)
  2776. break;
  2777. }
  2778. isl_vec_free(ineq);
  2779. clear_status(info);
  2780. init_status(info);
  2781. return i < n ? isl_stat_error : isl_stat_ok;
  2782. }
  2783. /* Insert the "n" integer division variables "expanded"
  2784. * into info->tab and info->bmap and
  2785. * update info->ineq with respect to the redundant constraints
  2786. * in the resulting tableau.
  2787. * "bmap" contains the result of this insertion in info->bmap,
  2788. * while info->bmap is the original version
  2789. * of "bmap", i.e., the one that corresponds to the current
  2790. * state of info->tab. The number of constraints in info->bmap
  2791. * is assumed to be the same as the number of constraints
  2792. * in info->tab. This is required to be able to detect
  2793. * the extra constraints in "bmap".
  2794. *
  2795. * In particular, introduce extra variables corresponding
  2796. * to the extra integer divisions and add the div constraints
  2797. * that were added to "bmap" after info->tab was created
  2798. * from info->bmap.
  2799. * Furthermore, check if these extra integer divisions happen
  2800. * to attain a fixed integer value in info->tab.
  2801. * If so, replace the corresponding div constraints by pairs
  2802. * of inequality constraints that fix these
  2803. * integer divisions to their single integer values.
  2804. * Replace info->bmap by "bmap" to match the changes to info->tab.
  2805. * info->ineq was computed without a tableau and therefore
  2806. * does not take into account the redundant constraints
  2807. * in the tableau. Mark them here.
  2808. * There is no need to check the newly added div constraints
  2809. * since they cannot be redundant.
  2810. * The redundancy check is not performed when constants have been discovered
  2811. * since info->ineq is completely thrown away in this case.
  2812. */
  2813. static isl_stat tab_insert_divs(struct isl_coalesce_info *info,
  2814. int n, struct isl_expanded *expanded, __isl_take isl_basic_map *bmap)
  2815. {
  2816. int i, n_ineq;
  2817. unsigned n_eq;
  2818. struct isl_tab_undo *snap;
  2819. int any;
  2820. if (!bmap)
  2821. return isl_stat_error;
  2822. if (info->bmap->n_eq + info->bmap->n_ineq != info->tab->n_con)
  2823. isl_die(isl_basic_map_get_ctx(bmap), isl_error_internal,
  2824. "original tableau does not correspond "
  2825. "to original basic map", goto error);
  2826. if (isl_tab_extend_vars(info->tab, n) < 0)
  2827. goto error;
  2828. if (isl_tab_extend_cons(info->tab, 2 * n) < 0)
  2829. goto error;
  2830. for (i = 0; i < n; ++i) {
  2831. if (isl_tab_insert_var(info->tab, expanded[i].pos) < 0)
  2832. goto error;
  2833. }
  2834. snap = isl_tab_snap(info->tab);
  2835. n_ineq = info->tab->n_con - info->tab->n_eq;
  2836. if (copy_ineq(info->tab, bmap) < 0)
  2837. goto error;
  2838. isl_basic_map_free(info->bmap);
  2839. info->bmap = bmap;
  2840. any = 0;
  2841. for (i = 0; i < n; ++i) {
  2842. expanded[i].cst = isl_tab_is_constant(info->tab,
  2843. expanded[i].pos, &expanded[i].val);
  2844. if (expanded[i].cst < 0)
  2845. return isl_stat_error;
  2846. if (expanded[i].cst)
  2847. any = 1;
  2848. }
  2849. if (any) {
  2850. if (isl_tab_rollback(info->tab, snap) < 0)
  2851. return isl_stat_error;
  2852. info->bmap = isl_basic_map_cow(info->bmap);
  2853. info->bmap = isl_basic_map_free_inequality(info->bmap, 2 * n);
  2854. if (info->bmap < 0)
  2855. return isl_stat_error;
  2856. return fix_constant_divs(info, n, expanded);
  2857. }
  2858. n_eq = info->bmap->n_eq;
  2859. for (i = 0; i < n_ineq; ++i) {
  2860. if (isl_tab_is_redundant(info->tab, n_eq + i))
  2861. info->ineq[i] = STATUS_REDUNDANT;
  2862. }
  2863. return isl_stat_ok;
  2864. error:
  2865. isl_basic_map_free(bmap);
  2866. return isl_stat_error;
  2867. }
  2868. /* Expand info->tab and info->bmap in the same way "bmap" was expanded
  2869. * in isl_basic_map_expand_divs using the expansion "exp" and
  2870. * update info->ineq with respect to the redundant constraints
  2871. * in the resulting tableau. info->bmap is the original version
  2872. * of "bmap", i.e., the one that corresponds to the current
  2873. * state of info->tab. The number of constraints in info->bmap
  2874. * is assumed to be the same as the number of constraints
  2875. * in info->tab. This is required to be able to detect
  2876. * the extra constraints in "bmap".
  2877. *
  2878. * Extract the positions where extra local variables are introduced
  2879. * from "exp" and call tab_insert_divs.
  2880. */
  2881. static isl_stat expand_tab(struct isl_coalesce_info *info, int *exp,
  2882. __isl_take isl_basic_map *bmap)
  2883. {
  2884. isl_ctx *ctx;
  2885. struct isl_expanded *expanded;
  2886. int i, j, k, n;
  2887. int extra_var;
  2888. isl_size total, n_div;
  2889. unsigned pos;
  2890. isl_stat r;
  2891. total = isl_basic_map_dim(bmap, isl_dim_all);
  2892. n_div = isl_basic_map_dim(bmap, isl_dim_div);
  2893. if (total < 0 || n_div < 0)
  2894. return isl_stat_error;
  2895. pos = total - n_div;
  2896. extra_var = total - info->tab->n_var;
  2897. n = n_div - extra_var;
  2898. ctx = isl_basic_map_get_ctx(bmap);
  2899. expanded = isl_calloc_array(ctx, struct isl_expanded, extra_var);
  2900. if (extra_var && !expanded)
  2901. goto error;
  2902. i = 0;
  2903. k = 0;
  2904. for (j = 0; j < n_div; ++j) {
  2905. if (i < n && exp[i] == j) {
  2906. ++i;
  2907. continue;
  2908. }
  2909. expanded[k++].pos = pos + j;
  2910. }
  2911. for (k = 0; k < extra_var; ++k)
  2912. isl_int_init(expanded[k].val);
  2913. r = tab_insert_divs(info, extra_var, expanded, bmap);
  2914. for (k = 0; k < extra_var; ++k)
  2915. isl_int_clear(expanded[k].val);
  2916. free(expanded);
  2917. return r;
  2918. error:
  2919. isl_basic_map_free(bmap);
  2920. return isl_stat_error;
  2921. }
  2922. /* Check if the union of the basic maps represented by info[i] and info[j]
  2923. * can be represented by a single basic map,
  2924. * after expanding the divs of info[i] to match those of info[j].
  2925. * If so, replace the pair by the single basic map and return
  2926. * isl_change_drop_first, isl_change_drop_second or isl_change_fuse.
  2927. * Otherwise, return isl_change_none.
  2928. *
  2929. * The caller has already checked for info[j] being a subset of info[i].
  2930. * If some of the divs of info[j] are unknown, then the expanded info[i]
  2931. * will not have the corresponding div constraints. The other patterns
  2932. * therefore cannot apply. Skip the computation in this case.
  2933. *
  2934. * The expansion is performed using the divs "div" and expansion "exp"
  2935. * computed by the caller.
  2936. * info[i].bmap has already been expanded and the result is passed in
  2937. * as "bmap".
  2938. * The "eq" and "ineq" fields of info[i] reflect the status of
  2939. * the constraints of the expanded "bmap" with respect to info[j].tab.
  2940. * However, inequality constraints that are redundant in info[i].tab
  2941. * have not yet been marked as such because no tableau was available.
  2942. *
  2943. * Replace info[i].bmap by "bmap" and expand info[i].tab as well,
  2944. * updating info[i].ineq with respect to the redundant constraints.
  2945. * Then try and coalesce the expanded info[i] with info[j],
  2946. * reusing the information in info[i].eq and info[i].ineq.
  2947. * If this does not result in any coalescing or if it results in info[j]
  2948. * getting dropped (which should not happen in practice, since the case
  2949. * of info[j] being a subset of info[i] has already been checked by
  2950. * the caller), then revert info[i] to its original state.
  2951. */
  2952. static enum isl_change coalesce_expand_tab_divs(__isl_take isl_basic_map *bmap,
  2953. int i, int j, struct isl_coalesce_info *info, __isl_keep isl_mat *div,
  2954. int *exp)
  2955. {
  2956. isl_bool known;
  2957. isl_basic_map *bmap_i;
  2958. struct isl_tab_undo *snap;
  2959. enum isl_change change = isl_change_none;
  2960. known = isl_basic_map_divs_known(info[j].bmap);
  2961. if (known < 0 || !known) {
  2962. clear_status(&info[i]);
  2963. isl_basic_map_free(bmap);
  2964. return known < 0 ? isl_change_error : isl_change_none;
  2965. }
  2966. bmap_i = isl_basic_map_copy(info[i].bmap);
  2967. snap = isl_tab_snap(info[i].tab);
  2968. if (expand_tab(&info[i], exp, bmap) < 0)
  2969. change = isl_change_error;
  2970. init_status(&info[j]);
  2971. if (change == isl_change_none)
  2972. change = coalesce_local_pair_reuse(i, j, info);
  2973. else
  2974. clear_status(&info[i]);
  2975. if (change != isl_change_none && change != isl_change_drop_second) {
  2976. isl_basic_map_free(bmap_i);
  2977. } else {
  2978. isl_basic_map_free(info[i].bmap);
  2979. info[i].bmap = bmap_i;
  2980. if (isl_tab_rollback(info[i].tab, snap) < 0)
  2981. change = isl_change_error;
  2982. }
  2983. return change;
  2984. }
  2985. /* Check if the union of "bmap" and the basic map represented by info[j]
  2986. * can be represented by a single basic map,
  2987. * after expanding the divs of "bmap" to match those of info[j].
  2988. * If so, replace the pair by the single basic map and return
  2989. * isl_change_drop_first, isl_change_drop_second or isl_change_fuse.
  2990. * Otherwise, return isl_change_none.
  2991. *
  2992. * In particular, check if the expanded "bmap" contains the basic map
  2993. * represented by the tableau info[j].tab.
  2994. * The expansion is performed using the divs "div" and expansion "exp"
  2995. * computed by the caller.
  2996. * Then we check if all constraints of the expanded "bmap" are valid for
  2997. * info[j].tab.
  2998. *
  2999. * If "i" is not equal to -1, then "bmap" is equal to info[i].bmap.
  3000. * In this case, the positions of the constraints of info[i].bmap
  3001. * with respect to the basic map represented by info[j] are stored
  3002. * in info[i].
  3003. *
  3004. * If the expanded "bmap" does not contain the basic map
  3005. * represented by the tableau info[j].tab and if "i" is not -1,
  3006. * i.e., if the original "bmap" is info[i].bmap, then expand info[i].tab
  3007. * as well and check if that results in coalescing.
  3008. */
  3009. static enum isl_change coalesce_with_expanded_divs(
  3010. __isl_keep isl_basic_map *bmap, int i, int j,
  3011. struct isl_coalesce_info *info, __isl_keep isl_mat *div, int *exp)
  3012. {
  3013. enum isl_change change = isl_change_none;
  3014. struct isl_coalesce_info info_local, *info_i;
  3015. info_i = i >= 0 ? &info[i] : &info_local;
  3016. init_status(info_i);
  3017. bmap = isl_basic_map_copy(bmap);
  3018. bmap = isl_basic_map_expand_divs(bmap, isl_mat_copy(div), exp);
  3019. bmap = isl_basic_map_mark_final(bmap);
  3020. if (!bmap)
  3021. goto error;
  3022. info_local.bmap = bmap;
  3023. info_i->eq = eq_status_in(bmap, info[j].tab);
  3024. if (bmap->n_eq && !info_i->eq)
  3025. goto error;
  3026. if (any_eq(info_i, STATUS_ERROR))
  3027. goto error;
  3028. if (any_eq(info_i, STATUS_SEPARATE))
  3029. goto done;
  3030. info_i->ineq = ineq_status_in(bmap, NULL, info[j].tab);
  3031. if (bmap->n_ineq && !info_i->ineq)
  3032. goto error;
  3033. if (any_ineq(info_i, STATUS_ERROR))
  3034. goto error;
  3035. if (any_ineq(info_i, STATUS_SEPARATE))
  3036. goto done;
  3037. if (all(info_i->eq, 2 * bmap->n_eq, STATUS_VALID) &&
  3038. all(info_i->ineq, bmap->n_ineq, STATUS_VALID)) {
  3039. drop(&info[j]);
  3040. change = isl_change_drop_second;
  3041. }
  3042. if (change == isl_change_none && i != -1)
  3043. return coalesce_expand_tab_divs(bmap, i, j, info, div, exp);
  3044. done:
  3045. isl_basic_map_free(bmap);
  3046. clear_status(info_i);
  3047. return change;
  3048. error:
  3049. isl_basic_map_free(bmap);
  3050. clear_status(info_i);
  3051. return isl_change_error;
  3052. }
  3053. /* Check if the union of "bmap_i" and the basic map represented by info[j]
  3054. * can be represented by a single basic map,
  3055. * after aligning the divs of "bmap_i" to match those of info[j].
  3056. * If so, replace the pair by the single basic map and return
  3057. * isl_change_drop_first, isl_change_drop_second or isl_change_fuse.
  3058. * Otherwise, return isl_change_none.
  3059. *
  3060. * In particular, check if "bmap_i" contains the basic map represented by
  3061. * info[j] after aligning the divs of "bmap_i" to those of info[j].
  3062. * Note that this can only succeed if the number of divs of "bmap_i"
  3063. * is smaller than (or equal to) the number of divs of info[j].
  3064. *
  3065. * We first check if the divs of "bmap_i" are all known and form a subset
  3066. * of those of info[j].bmap. If so, we pass control over to
  3067. * coalesce_with_expanded_divs.
  3068. *
  3069. * If "i" is not equal to -1, then "bmap" is equal to info[i].bmap.
  3070. */
  3071. static enum isl_change coalesce_after_aligning_divs(
  3072. __isl_keep isl_basic_map *bmap_i, int i, int j,
  3073. struct isl_coalesce_info *info)
  3074. {
  3075. isl_bool known;
  3076. isl_mat *div_i, *div_j, *div;
  3077. int *exp1 = NULL;
  3078. int *exp2 = NULL;
  3079. isl_ctx *ctx;
  3080. enum isl_change change;
  3081. known = isl_basic_map_divs_known(bmap_i);
  3082. if (known < 0)
  3083. return isl_change_error;
  3084. if (!known)
  3085. return isl_change_none;
  3086. ctx = isl_basic_map_get_ctx(bmap_i);
  3087. div_i = isl_basic_map_get_divs(bmap_i);
  3088. div_j = isl_basic_map_get_divs(info[j].bmap);
  3089. if (!div_i || !div_j)
  3090. goto error;
  3091. exp1 = isl_alloc_array(ctx, int, div_i->n_row);
  3092. exp2 = isl_alloc_array(ctx, int, div_j->n_row);
  3093. if ((div_i->n_row && !exp1) || (div_j->n_row && !exp2))
  3094. goto error;
  3095. div = isl_merge_divs(div_i, div_j, exp1, exp2);
  3096. if (!div)
  3097. goto error;
  3098. if (div->n_row == div_j->n_row)
  3099. change = coalesce_with_expanded_divs(bmap_i,
  3100. i, j, info, div, exp1);
  3101. else
  3102. change = isl_change_none;
  3103. isl_mat_free(div);
  3104. isl_mat_free(div_i);
  3105. isl_mat_free(div_j);
  3106. free(exp2);
  3107. free(exp1);
  3108. return change;
  3109. error:
  3110. isl_mat_free(div_i);
  3111. isl_mat_free(div_j);
  3112. free(exp1);
  3113. free(exp2);
  3114. return isl_change_error;
  3115. }
  3116. /* Check if basic map "j" is a subset of basic map "i" after
  3117. * exploiting the extra equalities of "j" to simplify the divs of "i".
  3118. * If so, remove basic map "j" and return isl_change_drop_second.
  3119. *
  3120. * If "j" does not have any equalities or if they are the same
  3121. * as those of "i", then we cannot exploit them to simplify the divs.
  3122. * Similarly, if there are no divs in "i", then they cannot be simplified.
  3123. * If, on the other hand, the affine hulls of "i" and "j" do not intersect,
  3124. * then "j" cannot be a subset of "i".
  3125. *
  3126. * Otherwise, we intersect "i" with the affine hull of "j" and then
  3127. * check if "j" is a subset of the result after aligning the divs.
  3128. * If so, then "j" is definitely a subset of "i" and can be removed.
  3129. * Note that if after intersection with the affine hull of "j".
  3130. * "i" still has more divs than "j", then there is no way we can
  3131. * align the divs of "i" to those of "j".
  3132. */
  3133. static enum isl_change coalesce_subset_with_equalities(int i, int j,
  3134. struct isl_coalesce_info *info)
  3135. {
  3136. isl_basic_map *hull_i, *hull_j, *bmap_i;
  3137. int equal, empty;
  3138. enum isl_change change;
  3139. if (info[j].bmap->n_eq == 0)
  3140. return isl_change_none;
  3141. if (info[i].bmap->n_div == 0)
  3142. return isl_change_none;
  3143. hull_i = isl_basic_map_copy(info[i].bmap);
  3144. hull_i = isl_basic_map_plain_affine_hull(hull_i);
  3145. hull_j = isl_basic_map_copy(info[j].bmap);
  3146. hull_j = isl_basic_map_plain_affine_hull(hull_j);
  3147. hull_j = isl_basic_map_intersect(hull_j, isl_basic_map_copy(hull_i));
  3148. equal = isl_basic_map_plain_is_equal(hull_i, hull_j);
  3149. empty = isl_basic_map_plain_is_empty(hull_j);
  3150. isl_basic_map_free(hull_i);
  3151. if (equal < 0 || equal || empty < 0 || empty) {
  3152. isl_basic_map_free(hull_j);
  3153. if (equal < 0 || empty < 0)
  3154. return isl_change_error;
  3155. return isl_change_none;
  3156. }
  3157. bmap_i = isl_basic_map_copy(info[i].bmap);
  3158. bmap_i = isl_basic_map_intersect(bmap_i, hull_j);
  3159. if (!bmap_i)
  3160. return isl_change_error;
  3161. if (bmap_i->n_div > info[j].bmap->n_div) {
  3162. isl_basic_map_free(bmap_i);
  3163. return isl_change_none;
  3164. }
  3165. change = coalesce_after_aligning_divs(bmap_i, -1, j, info);
  3166. isl_basic_map_free(bmap_i);
  3167. return change;
  3168. }
  3169. /* Check if the union of the basic maps represented by info[i] and info[j]
  3170. * can be represented by a single basic map, by aligning or equating
  3171. * their integer divisions.
  3172. * If so, replace the pair by the single basic map and return
  3173. * isl_change_drop_first, isl_change_drop_second or isl_change_fuse.
  3174. * Otherwise, return isl_change_none.
  3175. *
  3176. * Note that we only perform any test if the number of divs is different
  3177. * in the two basic maps. In case the number of divs is the same,
  3178. * we have already established that the divs are different
  3179. * in the two basic maps.
  3180. * In particular, if the number of divs of basic map i is smaller than
  3181. * the number of divs of basic map j, then we check if j is a subset of i
  3182. * and vice versa.
  3183. */
  3184. static enum isl_change coalesce_divs(int i, int j,
  3185. struct isl_coalesce_info *info)
  3186. {
  3187. enum isl_change change = isl_change_none;
  3188. if (info[i].bmap->n_div < info[j].bmap->n_div)
  3189. change = coalesce_after_aligning_divs(info[i].bmap, i, j, info);
  3190. if (change != isl_change_none)
  3191. return change;
  3192. if (info[j].bmap->n_div < info[i].bmap->n_div)
  3193. change = coalesce_after_aligning_divs(info[j].bmap, j, i, info);
  3194. if (change != isl_change_none)
  3195. return invert_change(change);
  3196. change = coalesce_subset_with_equalities(i, j, info);
  3197. if (change != isl_change_none)
  3198. return change;
  3199. change = coalesce_subset_with_equalities(j, i, info);
  3200. if (change != isl_change_none)
  3201. return invert_change(change);
  3202. return isl_change_none;
  3203. }
  3204. /* Does "bmap" involve any divs that themselves refer to divs?
  3205. */
  3206. static isl_bool has_nested_div(__isl_keep isl_basic_map *bmap)
  3207. {
  3208. int i;
  3209. isl_size total;
  3210. isl_size n_div;
  3211. total = isl_basic_map_dim(bmap, isl_dim_all);
  3212. n_div = isl_basic_map_dim(bmap, isl_dim_div);
  3213. if (total < 0 || n_div < 0)
  3214. return isl_bool_error;
  3215. total -= n_div;
  3216. for (i = 0; i < n_div; ++i)
  3217. if (isl_seq_first_non_zero(bmap->div[i] + 2 + total,
  3218. n_div) != -1)
  3219. return isl_bool_true;
  3220. return isl_bool_false;
  3221. }
  3222. /* Return a list of affine expressions, one for each integer division
  3223. * in "bmap_i". For each integer division that also appears in "bmap_j",
  3224. * the affine expression is set to NaN. The number of NaNs in the list
  3225. * is equal to the number of integer divisions in "bmap_j".
  3226. * For the other integer divisions of "bmap_i", the corresponding
  3227. * element in the list is a purely affine expression equal to the integer
  3228. * division in "hull".
  3229. * If no such list can be constructed, then the number of elements
  3230. * in the returned list is smaller than the number of integer divisions
  3231. * in "bmap_i".
  3232. * The integer division of "bmap_i" and "bmap_j" are assumed to be known and
  3233. * not contain any nested divs.
  3234. */
  3235. static __isl_give isl_aff_list *set_up_substitutions(
  3236. __isl_keep isl_basic_map *bmap_i, __isl_keep isl_basic_map *bmap_j,
  3237. __isl_take isl_basic_map *hull)
  3238. {
  3239. isl_size n_div_i, n_div_j, total;
  3240. isl_ctx *ctx;
  3241. isl_local_space *ls;
  3242. isl_basic_set *wrap_hull;
  3243. isl_aff *aff_nan;
  3244. isl_aff_list *list;
  3245. int i, j;
  3246. n_div_i = isl_basic_map_dim(bmap_i, isl_dim_div);
  3247. n_div_j = isl_basic_map_dim(bmap_j, isl_dim_div);
  3248. total = isl_basic_map_dim(bmap_i, isl_dim_all);
  3249. if (!hull || n_div_i < 0 || n_div_j < 0 || total < 0)
  3250. return NULL;
  3251. ctx = isl_basic_map_get_ctx(hull);
  3252. total -= n_div_i;
  3253. ls = isl_basic_map_get_local_space(bmap_i);
  3254. ls = isl_local_space_wrap(ls);
  3255. wrap_hull = isl_basic_map_wrap(hull);
  3256. aff_nan = isl_aff_nan_on_domain(isl_local_space_copy(ls));
  3257. list = isl_aff_list_alloc(ctx, n_div_i);
  3258. j = 0;
  3259. for (i = 0; i < n_div_i; ++i) {
  3260. isl_aff *aff;
  3261. isl_size n_div;
  3262. if (j < n_div_j &&
  3263. isl_basic_map_equal_div_expr_part(bmap_i, i, bmap_j, j,
  3264. 0, 2 + total)) {
  3265. ++j;
  3266. list = isl_aff_list_add(list, isl_aff_copy(aff_nan));
  3267. continue;
  3268. }
  3269. if (n_div_i - i <= n_div_j - j)
  3270. break;
  3271. aff = isl_local_space_get_div(ls, i);
  3272. aff = isl_aff_substitute_equalities(aff,
  3273. isl_basic_set_copy(wrap_hull));
  3274. aff = isl_aff_floor(aff);
  3275. n_div = isl_aff_dim(aff, isl_dim_div);
  3276. if (n_div < 0)
  3277. goto error;
  3278. if (n_div != 0) {
  3279. isl_aff_free(aff);
  3280. break;
  3281. }
  3282. list = isl_aff_list_add(list, aff);
  3283. }
  3284. isl_aff_free(aff_nan);
  3285. isl_local_space_free(ls);
  3286. isl_basic_set_free(wrap_hull);
  3287. return list;
  3288. error:
  3289. isl_aff_free(aff_nan);
  3290. isl_local_space_free(ls);
  3291. isl_basic_set_free(wrap_hull);
  3292. isl_aff_list_free(list);
  3293. return NULL;
  3294. }
  3295. /* Add variables to info->bmap and info->tab corresponding to the elements
  3296. * in "list" that are not set to NaN.
  3297. * "extra_var" is the number of these elements.
  3298. * "dim" is the offset in the variables of "tab" where we should
  3299. * start considering the elements in "list".
  3300. * When this function returns, the total number of variables in "tab"
  3301. * is equal to "dim" plus the number of elements in "list".
  3302. *
  3303. * The newly added existentially quantified variables are not given
  3304. * an explicit representation because the corresponding div constraints
  3305. * do not appear in info->bmap. These constraints are not added
  3306. * to info->bmap because for internal consistency, they would need to
  3307. * be added to info->tab as well, where they could combine with the equality
  3308. * that is added later to result in constraints that do not hold
  3309. * in the original input.
  3310. */
  3311. static isl_stat add_sub_vars(struct isl_coalesce_info *info,
  3312. __isl_keep isl_aff_list *list, int dim, int extra_var)
  3313. {
  3314. int i, j, d;
  3315. isl_size n;
  3316. info->bmap = isl_basic_map_cow(info->bmap);
  3317. info->bmap = isl_basic_map_extend(info->bmap, extra_var, 0, 0);
  3318. n = isl_aff_list_n_aff(list);
  3319. if (!info->bmap || n < 0)
  3320. return isl_stat_error;
  3321. for (i = 0; i < n; ++i) {
  3322. int is_nan;
  3323. isl_aff *aff;
  3324. aff = isl_aff_list_get_aff(list, i);
  3325. is_nan = isl_aff_is_nan(aff);
  3326. isl_aff_free(aff);
  3327. if (is_nan < 0)
  3328. return isl_stat_error;
  3329. if (is_nan)
  3330. continue;
  3331. if (isl_tab_insert_var(info->tab, dim + i) < 0)
  3332. return isl_stat_error;
  3333. d = isl_basic_map_alloc_div(info->bmap);
  3334. if (d < 0)
  3335. return isl_stat_error;
  3336. info->bmap = isl_basic_map_mark_div_unknown(info->bmap, d);
  3337. for (j = d; j > i; --j)
  3338. info->bmap = isl_basic_map_swap_div(info->bmap,
  3339. j - 1, j);
  3340. if (!info->bmap)
  3341. return isl_stat_error;
  3342. }
  3343. return isl_stat_ok;
  3344. }
  3345. /* For each element in "list" that is not set to NaN, fix the corresponding
  3346. * variable in "tab" to the purely affine expression defined by the element.
  3347. * "dim" is the offset in the variables of "tab" where we should
  3348. * start considering the elements in "list".
  3349. *
  3350. * This function assumes that a sufficient number of rows and
  3351. * elements in the constraint array are available in the tableau.
  3352. */
  3353. static isl_stat add_sub_equalities(struct isl_tab *tab,
  3354. __isl_keep isl_aff_list *list, int dim)
  3355. {
  3356. int i;
  3357. isl_size n;
  3358. isl_ctx *ctx;
  3359. isl_vec *sub;
  3360. isl_aff *aff;
  3361. n = isl_aff_list_n_aff(list);
  3362. if (n < 0)
  3363. return isl_stat_error;
  3364. ctx = isl_tab_get_ctx(tab);
  3365. sub = isl_vec_alloc(ctx, 1 + dim + n);
  3366. if (!sub)
  3367. return isl_stat_error;
  3368. isl_seq_clr(sub->el + 1 + dim, n);
  3369. for (i = 0; i < n; ++i) {
  3370. aff = isl_aff_list_get_aff(list, i);
  3371. if (!aff)
  3372. goto error;
  3373. if (isl_aff_is_nan(aff)) {
  3374. isl_aff_free(aff);
  3375. continue;
  3376. }
  3377. isl_seq_cpy(sub->el, aff->v->el + 1, 1 + dim);
  3378. isl_int_neg(sub->el[1 + dim + i], aff->v->el[0]);
  3379. if (isl_tab_add_eq(tab, sub->el) < 0)
  3380. goto error;
  3381. isl_int_set_si(sub->el[1 + dim + i], 0);
  3382. isl_aff_free(aff);
  3383. }
  3384. isl_vec_free(sub);
  3385. return isl_stat_ok;
  3386. error:
  3387. isl_aff_free(aff);
  3388. isl_vec_free(sub);
  3389. return isl_stat_error;
  3390. }
  3391. /* Add variables to info->tab and info->bmap corresponding to the elements
  3392. * in "list" that are not set to NaN. The value of the added variable
  3393. * in info->tab is fixed to the purely affine expression defined by the element.
  3394. * "dim" is the offset in the variables of info->tab where we should
  3395. * start considering the elements in "list".
  3396. * When this function returns, the total number of variables in info->tab
  3397. * is equal to "dim" plus the number of elements in "list".
  3398. */
  3399. static isl_stat add_subs(struct isl_coalesce_info *info,
  3400. __isl_keep isl_aff_list *list, int dim)
  3401. {
  3402. int extra_var;
  3403. isl_size n;
  3404. n = isl_aff_list_n_aff(list);
  3405. if (n < 0)
  3406. return isl_stat_error;
  3407. extra_var = n - (info->tab->n_var - dim);
  3408. if (isl_tab_extend_vars(info->tab, extra_var) < 0)
  3409. return isl_stat_error;
  3410. if (isl_tab_extend_cons(info->tab, 2 * extra_var) < 0)
  3411. return isl_stat_error;
  3412. if (add_sub_vars(info, list, dim, extra_var) < 0)
  3413. return isl_stat_error;
  3414. return add_sub_equalities(info->tab, list, dim);
  3415. }
  3416. /* Coalesce basic map "j" into basic map "i" after adding the extra integer
  3417. * divisions in "i" but not in "j" to basic map "j", with values
  3418. * specified by "list". The total number of elements in "list"
  3419. * is equal to the number of integer divisions in "i", while the number
  3420. * of NaN elements in the list is equal to the number of integer divisions
  3421. * in "j".
  3422. *
  3423. * If no coalescing can be performed, then we need to revert basic map "j"
  3424. * to its original state. We do the same if basic map "i" gets dropped
  3425. * during the coalescing, even though this should not happen in practice
  3426. * since we have already checked for "j" being a subset of "i"
  3427. * before we reach this stage.
  3428. */
  3429. static enum isl_change coalesce_with_subs(int i, int j,
  3430. struct isl_coalesce_info *info, __isl_keep isl_aff_list *list)
  3431. {
  3432. isl_basic_map *bmap_j;
  3433. struct isl_tab_undo *snap;
  3434. isl_size dim, n_div;
  3435. enum isl_change change;
  3436. bmap_j = isl_basic_map_copy(info[j].bmap);
  3437. snap = isl_tab_snap(info[j].tab);
  3438. dim = isl_basic_map_dim(bmap_j, isl_dim_all);
  3439. n_div = isl_basic_map_dim(bmap_j, isl_dim_div);
  3440. if (dim < 0 || n_div < 0)
  3441. goto error;
  3442. dim -= n_div;
  3443. if (add_subs(&info[j], list, dim) < 0)
  3444. goto error;
  3445. change = coalesce_local_pair(i, j, info);
  3446. if (change != isl_change_none && change != isl_change_drop_first) {
  3447. isl_basic_map_free(bmap_j);
  3448. } else {
  3449. isl_basic_map_free(info[j].bmap);
  3450. info[j].bmap = bmap_j;
  3451. if (isl_tab_rollback(info[j].tab, snap) < 0)
  3452. return isl_change_error;
  3453. }
  3454. return change;
  3455. error:
  3456. isl_basic_map_free(bmap_j);
  3457. return isl_change_error;
  3458. }
  3459. /* Check if we can coalesce basic map "j" into basic map "i" after copying
  3460. * those extra integer divisions in "i" that can be simplified away
  3461. * using the extra equalities in "j".
  3462. * All divs are assumed to be known and not contain any nested divs.
  3463. *
  3464. * We first check if there are any extra equalities in "j" that we
  3465. * can exploit. Then we check if every integer division in "i"
  3466. * either already appears in "j" or can be simplified using the
  3467. * extra equalities to a purely affine expression.
  3468. * If these tests succeed, then we try to coalesce the two basic maps
  3469. * by introducing extra dimensions in "j" corresponding to
  3470. * the extra integer divisions "i" fixed to the corresponding
  3471. * purely affine expression.
  3472. */
  3473. static enum isl_change check_coalesce_into_eq(int i, int j,
  3474. struct isl_coalesce_info *info)
  3475. {
  3476. isl_size n_div_i, n_div_j, n;
  3477. isl_basic_map *hull_i, *hull_j;
  3478. isl_bool equal, empty;
  3479. isl_aff_list *list;
  3480. enum isl_change change;
  3481. n_div_i = isl_basic_map_dim(info[i].bmap, isl_dim_div);
  3482. n_div_j = isl_basic_map_dim(info[j].bmap, isl_dim_div);
  3483. if (n_div_i < 0 || n_div_j < 0)
  3484. return isl_change_error;
  3485. if (n_div_i <= n_div_j)
  3486. return isl_change_none;
  3487. if (info[j].bmap->n_eq == 0)
  3488. return isl_change_none;
  3489. hull_i = isl_basic_map_copy(info[i].bmap);
  3490. hull_i = isl_basic_map_plain_affine_hull(hull_i);
  3491. hull_j = isl_basic_map_copy(info[j].bmap);
  3492. hull_j = isl_basic_map_plain_affine_hull(hull_j);
  3493. hull_j = isl_basic_map_intersect(hull_j, isl_basic_map_copy(hull_i));
  3494. equal = isl_basic_map_plain_is_equal(hull_i, hull_j);
  3495. empty = isl_basic_map_plain_is_empty(hull_j);
  3496. isl_basic_map_free(hull_i);
  3497. if (equal < 0 || empty < 0)
  3498. goto error;
  3499. if (equal || empty) {
  3500. isl_basic_map_free(hull_j);
  3501. return isl_change_none;
  3502. }
  3503. list = set_up_substitutions(info[i].bmap, info[j].bmap, hull_j);
  3504. if (!list)
  3505. return isl_change_error;
  3506. n = isl_aff_list_n_aff(list);
  3507. if (n < 0)
  3508. change = isl_change_error;
  3509. else if (n < n_div_i)
  3510. change = isl_change_none;
  3511. else
  3512. change = coalesce_with_subs(i, j, info, list);
  3513. isl_aff_list_free(list);
  3514. return change;
  3515. error:
  3516. isl_basic_map_free(hull_j);
  3517. return isl_change_error;
  3518. }
  3519. /* Check if we can coalesce basic maps "i" and "j" after copying
  3520. * those extra integer divisions in one of the basic maps that can
  3521. * be simplified away using the extra equalities in the other basic map.
  3522. * We require all divs to be known in both basic maps.
  3523. * Furthermore, to simplify the comparison of div expressions,
  3524. * we do not allow any nested integer divisions.
  3525. */
  3526. static enum isl_change check_coalesce_eq(int i, int j,
  3527. struct isl_coalesce_info *info)
  3528. {
  3529. isl_bool known, nested;
  3530. enum isl_change change;
  3531. known = isl_basic_map_divs_known(info[i].bmap);
  3532. if (known < 0 || !known)
  3533. return known < 0 ? isl_change_error : isl_change_none;
  3534. known = isl_basic_map_divs_known(info[j].bmap);
  3535. if (known < 0 || !known)
  3536. return known < 0 ? isl_change_error : isl_change_none;
  3537. nested = has_nested_div(info[i].bmap);
  3538. if (nested < 0 || nested)
  3539. return nested < 0 ? isl_change_error : isl_change_none;
  3540. nested = has_nested_div(info[j].bmap);
  3541. if (nested < 0 || nested)
  3542. return nested < 0 ? isl_change_error : isl_change_none;
  3543. change = check_coalesce_into_eq(i, j, info);
  3544. if (change != isl_change_none)
  3545. return change;
  3546. change = check_coalesce_into_eq(j, i, info);
  3547. if (change != isl_change_none)
  3548. return invert_change(change);
  3549. return isl_change_none;
  3550. }
  3551. /* Check if the union of the given pair of basic maps
  3552. * can be represented by a single basic map.
  3553. * If so, replace the pair by the single basic map and return
  3554. * isl_change_drop_first, isl_change_drop_second or isl_change_fuse.
  3555. * Otherwise, return isl_change_none.
  3556. *
  3557. * We first check if the two basic maps live in the same local space,
  3558. * after aligning the divs that differ by only an integer constant.
  3559. * If so, we do the complete check. Otherwise, we check if they have
  3560. * the same number of integer divisions and can be coalesced, if one is
  3561. * an obvious subset of the other or if the extra integer divisions
  3562. * of one basic map can be simplified away using the extra equalities
  3563. * of the other basic map.
  3564. *
  3565. * Note that trying to coalesce pairs of disjuncts with the same
  3566. * number, but different local variables may drop the explicit
  3567. * representation of some of these local variables.
  3568. * This operation is therefore not performed when
  3569. * the "coalesce_preserve_locals" option is set.
  3570. */
  3571. static enum isl_change coalesce_pair(int i, int j,
  3572. struct isl_coalesce_info *info)
  3573. {
  3574. int preserve;
  3575. isl_bool same;
  3576. enum isl_change change;
  3577. isl_ctx *ctx;
  3578. if (harmonize_divs(&info[i], &info[j]) < 0)
  3579. return isl_change_error;
  3580. same = same_divs(info[i].bmap, info[j].bmap);
  3581. if (same < 0)
  3582. return isl_change_error;
  3583. if (same)
  3584. return coalesce_local_pair(i, j, info);
  3585. ctx = isl_basic_map_get_ctx(info[i].bmap);
  3586. preserve = isl_options_get_coalesce_preserve_locals(ctx);
  3587. if (!preserve && info[i].bmap->n_div == info[j].bmap->n_div) {
  3588. change = coalesce_local_pair(i, j, info);
  3589. if (change != isl_change_none)
  3590. return change;
  3591. }
  3592. change = coalesce_divs(i, j, info);
  3593. if (change != isl_change_none)
  3594. return change;
  3595. return check_coalesce_eq(i, j, info);
  3596. }
  3597. /* Return the maximum of "a" and "b".
  3598. */
  3599. static int isl_max(int a, int b)
  3600. {
  3601. return a > b ? a : b;
  3602. }
  3603. /* Pairwise coalesce the basic maps in the range [start1, end1[ of "info"
  3604. * with those in the range [start2, end2[, skipping basic maps
  3605. * that have been removed (either before or within this function).
  3606. *
  3607. * For each basic map i in the first range, we check if it can be coalesced
  3608. * with respect to any previously considered basic map j in the second range.
  3609. * If i gets dropped (because it was a subset of some j), then
  3610. * we can move on to the next basic map.
  3611. * If j gets dropped, we need to continue checking against the other
  3612. * previously considered basic maps.
  3613. * If the two basic maps got fused, then we recheck the fused basic map
  3614. * against the previously considered basic maps, starting at i + 1
  3615. * (even if start2 is greater than i + 1).
  3616. */
  3617. static int coalesce_range(isl_ctx *ctx, struct isl_coalesce_info *info,
  3618. int start1, int end1, int start2, int end2)
  3619. {
  3620. int i, j;
  3621. for (i = end1 - 1; i >= start1; --i) {
  3622. if (info[i].removed)
  3623. continue;
  3624. for (j = isl_max(i + 1, start2); j < end2; ++j) {
  3625. enum isl_change changed;
  3626. if (info[j].removed)
  3627. continue;
  3628. if (info[i].removed)
  3629. isl_die(ctx, isl_error_internal,
  3630. "basic map unexpectedly removed",
  3631. return -1);
  3632. changed = coalesce_pair(i, j, info);
  3633. switch (changed) {
  3634. case isl_change_error:
  3635. return -1;
  3636. case isl_change_none:
  3637. case isl_change_drop_second:
  3638. continue;
  3639. case isl_change_drop_first:
  3640. j = end2;
  3641. break;
  3642. case isl_change_fuse:
  3643. j = i;
  3644. break;
  3645. }
  3646. }
  3647. }
  3648. return 0;
  3649. }
  3650. /* Pairwise coalesce the basic maps described by the "n" elements of "info".
  3651. *
  3652. * We consider groups of basic maps that live in the same apparent
  3653. * affine hull and we first coalesce within such a group before we
  3654. * coalesce the elements in the group with elements of previously
  3655. * considered groups. If a fuse happens during the second phase,
  3656. * then we also reconsider the elements within the group.
  3657. */
  3658. static int coalesce(isl_ctx *ctx, int n, struct isl_coalesce_info *info)
  3659. {
  3660. int start, end;
  3661. for (end = n; end > 0; end = start) {
  3662. start = end - 1;
  3663. while (start >= 1 &&
  3664. info[start - 1].hull_hash == info[start].hull_hash)
  3665. start--;
  3666. if (coalesce_range(ctx, info, start, end, start, end) < 0)
  3667. return -1;
  3668. if (coalesce_range(ctx, info, start, end, end, n) < 0)
  3669. return -1;
  3670. }
  3671. return 0;
  3672. }
  3673. /* Update the basic maps in "map" based on the information in "info".
  3674. * In particular, remove the basic maps that have been marked removed and
  3675. * update the others based on the information in the corresponding tableau.
  3676. * Since we detected implicit equalities without calling
  3677. * isl_basic_map_gauss, we need to do it now.
  3678. * Also call isl_basic_map_simplify if we may have lost the definition
  3679. * of one or more integer divisions.
  3680. * If a basic map is still equal to the one from which the corresponding "info"
  3681. * entry was created, then redundant constraint and
  3682. * implicit equality constraint detection have been performed
  3683. * on the corresponding tableau and the basic map can be marked as such.
  3684. */
  3685. static __isl_give isl_map *update_basic_maps(__isl_take isl_map *map,
  3686. int n, struct isl_coalesce_info *info)
  3687. {
  3688. int i;
  3689. if (!map)
  3690. return NULL;
  3691. for (i = n - 1; i >= 0; --i) {
  3692. if (info[i].removed) {
  3693. isl_basic_map_free(map->p[i]);
  3694. if (i != map->n - 1)
  3695. map->p[i] = map->p[map->n - 1];
  3696. map->n--;
  3697. continue;
  3698. }
  3699. info[i].bmap = isl_basic_map_update_from_tab(info[i].bmap,
  3700. info[i].tab);
  3701. info[i].bmap = isl_basic_map_gauss(info[i].bmap, NULL);
  3702. if (info[i].simplify)
  3703. info[i].bmap = isl_basic_map_simplify(info[i].bmap);
  3704. info[i].bmap = isl_basic_map_finalize(info[i].bmap);
  3705. if (!info[i].bmap)
  3706. return isl_map_free(map);
  3707. if (!info[i].modified) {
  3708. ISL_F_SET(info[i].bmap, ISL_BASIC_MAP_NO_IMPLICIT);
  3709. ISL_F_SET(info[i].bmap, ISL_BASIC_MAP_NO_REDUNDANT);
  3710. }
  3711. isl_basic_map_free(map->p[i]);
  3712. map->p[i] = info[i].bmap;
  3713. info[i].bmap = NULL;
  3714. }
  3715. return map;
  3716. }
  3717. /* For each pair of basic maps in the map, check if the union of the two
  3718. * can be represented by a single basic map.
  3719. * If so, replace the pair by the single basic map and start over.
  3720. *
  3721. * We factor out any (hidden) common factor from the constraint
  3722. * coefficients to improve the detection of adjacent constraints.
  3723. * Note that this function does not call isl_basic_map_gauss,
  3724. * but it does make sure that only a single copy of the basic map
  3725. * is affected. This means that isl_basic_map_gauss may have
  3726. * to be called at the end of the computation (in update_basic_maps)
  3727. * on this single copy to ensure that
  3728. * the basic maps are not left in an unexpected state.
  3729. *
  3730. * Since we are constructing the tableaus of the basic maps anyway,
  3731. * we exploit them to detect implicit equalities and redundant constraints.
  3732. * This also helps the coalescing as it can ignore the redundant constraints.
  3733. * In order to avoid confusion, we make all implicit equalities explicit
  3734. * in the basic maps. If the basic map only has a single reference
  3735. * (this happens in particular if it was modified by
  3736. * isl_basic_map_reduce_coefficients), then isl_basic_map_gauss
  3737. * does not get called on the result. The call to
  3738. * isl_basic_map_gauss in update_basic_maps resolves this as well.
  3739. * For each basic map, we also compute the hash of the apparent affine hull
  3740. * for use in coalesce.
  3741. */
  3742. __isl_give isl_map *isl_map_coalesce(__isl_take isl_map *map)
  3743. {
  3744. int i;
  3745. unsigned n;
  3746. isl_ctx *ctx;
  3747. struct isl_coalesce_info *info = NULL;
  3748. map = isl_map_remove_empty_parts(map);
  3749. if (!map)
  3750. return NULL;
  3751. if (map->n <= 1)
  3752. return map;
  3753. ctx = isl_map_get_ctx(map);
  3754. map = isl_map_sort_divs(map);
  3755. map = isl_map_cow(map);
  3756. if (!map)
  3757. return NULL;
  3758. n = map->n;
  3759. info = isl_calloc_array(map->ctx, struct isl_coalesce_info, n);
  3760. if (!info)
  3761. goto error;
  3762. for (i = 0; i < map->n; ++i) {
  3763. map->p[i] = isl_basic_map_reduce_coefficients(map->p[i]);
  3764. if (!map->p[i])
  3765. goto error;
  3766. info[i].bmap = isl_basic_map_copy(map->p[i]);
  3767. info[i].tab = isl_tab_from_basic_map(info[i].bmap, 0);
  3768. if (!info[i].tab)
  3769. goto error;
  3770. if (!ISL_F_ISSET(info[i].bmap, ISL_BASIC_MAP_NO_IMPLICIT))
  3771. if (isl_tab_detect_implicit_equalities(info[i].tab) < 0)
  3772. goto error;
  3773. info[i].bmap = isl_tab_make_equalities_explicit(info[i].tab,
  3774. info[i].bmap);
  3775. if (!info[i].bmap)
  3776. goto error;
  3777. if (!ISL_F_ISSET(info[i].bmap, ISL_BASIC_MAP_NO_REDUNDANT))
  3778. if (isl_tab_detect_redundant(info[i].tab) < 0)
  3779. goto error;
  3780. if (coalesce_info_set_hull_hash(&info[i]) < 0)
  3781. goto error;
  3782. }
  3783. for (i = map->n - 1; i >= 0; --i)
  3784. if (info[i].tab->empty)
  3785. drop(&info[i]);
  3786. if (coalesce(ctx, n, info) < 0)
  3787. goto error;
  3788. map = update_basic_maps(map, n, info);
  3789. clear_coalesce_info(n, info);
  3790. return map;
  3791. error:
  3792. clear_coalesce_info(n, info);
  3793. isl_map_free(map);
  3794. return NULL;
  3795. }
  3796. /* For each pair of basic sets in the set, check if the union of the two
  3797. * can be represented by a single basic set.
  3798. * If so, replace the pair by the single basic set and start over.
  3799. */
  3800. __isl_give isl_set *isl_set_coalesce(__isl_take isl_set *set)
  3801. {
  3802. return set_from_map(isl_map_coalesce(set_to_map(set)));
  3803. }