omega.c 128 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568
  1. /* Source code for an implementation of the Omega test, an integer
  2. programming algorithm for dependence analysis, by William Pugh,
  3. appeared in Supercomputing '91 and CACM Aug 92.
  4. This code has no license restrictions, and is considered public
  5. domain.
  6. Changes copyright (C) 2005-2015 Free Software Foundation, Inc.
  7. Contributed by Sebastian Pop <sebastian.pop@inria.fr>
  8. This file is part of GCC.
  9. GCC is free software; you can redistribute it and/or modify it under
  10. the terms of the GNU General Public License as published by the Free
  11. Software Foundation; either version 3, or (at your option) any later
  12. version.
  13. GCC is distributed in the hope that it will be useful, but WITHOUT ANY
  14. WARRANTY; without even the implied warranty of MERCHANTABILITY or
  15. FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  16. for more details.
  17. You should have received a copy of the GNU General Public License
  18. along with GCC; see the file COPYING3. If not see
  19. <http://www.gnu.org/licenses/>. */
  20. /* For a detailed description, see "Constraint-Based Array Dependence
  21. Analysis" William Pugh, David Wonnacott, TOPLAS'98 and David
  22. Wonnacott's thesis:
  23. ftp://ftp.cs.umd.edu/pub/omega/davewThesis/davewThesis.ps.gz
  24. */
  25. #include "config.h"
  26. #include "system.h"
  27. #include "coretypes.h"
  28. #include "hash-set.h"
  29. #include "machmode.h"
  30. #include "vec.h"
  31. #include "double-int.h"
  32. #include "input.h"
  33. #include "alias.h"
  34. #include "symtab.h"
  35. #include "options.h"
  36. #include "wide-int.h"
  37. #include "inchash.h"
  38. #include "tree.h"
  39. #include "diagnostic-core.h"
  40. #include "dumpfile.h"
  41. #include "omega.h"
  42. /* When set to true, keep substitution variables. When set to false,
  43. resurrect substitution variables (convert substitutions back to EQs). */
  44. static bool omega_reduce_with_subs = true;
  45. /* When set to true, omega_simplify_problem checks for problem with no
  46. solutions, calling verify_omega_pb. */
  47. static bool omega_verify_simplification = false;
  48. /* When set to true, only produce a single simplified result. */
  49. static bool omega_single_result = false;
  50. /* Set return_single_result to 1 when omega_single_result is true. */
  51. static int return_single_result = 0;
  52. /* Hash table for equations generated by the solver. */
  53. #define HASH_TABLE_SIZE PARAM_VALUE (PARAM_OMEGA_HASH_TABLE_SIZE)
  54. #define MAX_KEYS PARAM_VALUE (PARAM_OMEGA_MAX_KEYS)
  55. static eqn hash_master;
  56. static int next_key;
  57. static int hash_version = 0;
  58. /* Set to true for making the solver enter in approximation mode. */
  59. static bool in_approximate_mode = false;
  60. /* When set to zero, the solver is allowed to add new equalities to
  61. the problem to be solved. */
  62. static int conservative = 0;
  63. /* Set to omega_true when the problem was successfully reduced, set to
  64. omega_unknown when the solver is unable to determine an answer. */
  65. static enum omega_result omega_found_reduction;
  66. /* Set to true when the solver is allowed to add omega_red equations. */
  67. static bool create_color = false;
  68. /* Set to nonzero when the problem to be solved can be reduced. */
  69. static int may_be_red = 0;
  70. /* When false, there should be no substitution equations in the
  71. simplified problem. */
  72. static int please_no_equalities_in_simplified_problems = 0;
  73. /* Variables names for pretty printing. */
  74. static char wild_name[200][40];
  75. /* Pointer to the void problem. */
  76. static omega_pb no_problem = (omega_pb) 0;
  77. /* Pointer to the problem to be solved. */
  78. static omega_pb original_problem = (omega_pb) 0;
  79. /* Return the integer A divided by B. */
  80. static inline int
  81. int_div (int a, int b)
  82. {
  83. if (a > 0)
  84. return a/b;
  85. else
  86. return -((-a + b - 1)/b);
  87. }
  88. /* Return the integer A modulo B. */
  89. static inline int
  90. int_mod (int a, int b)
  91. {
  92. return a - b * int_div (a, b);
  93. }
  94. /* Test whether equation E is red. */
  95. static inline bool
  96. omega_eqn_is_red (eqn e, int desired_res)
  97. {
  98. return (desired_res == omega_simplify && e->color == omega_red);
  99. }
  100. /* Return a string for VARIABLE. */
  101. static inline char *
  102. omega_var_to_str (int variable)
  103. {
  104. if (0 <= variable && variable <= 20)
  105. return wild_name[variable];
  106. if (-20 < variable && variable < 0)
  107. return wild_name[40 + variable];
  108. /* Collapse all the entries that would have overflowed. */
  109. return wild_name[21];
  110. }
  111. /* Return a string for variable I in problem PB. */
  112. static inline char *
  113. omega_variable_to_str (omega_pb pb, int i)
  114. {
  115. return omega_var_to_str (pb->var[i]);
  116. }
  117. /* Do nothing function: used for default initializations. */
  118. void
  119. omega_no_procedure (omega_pb pb ATTRIBUTE_UNUSED)
  120. {
  121. }
  122. void (*omega_when_reduced) (omega_pb) = omega_no_procedure;
  123. /* Print to FILE from PB equation E with all its coefficients
  124. multiplied by C. */
  125. static void
  126. omega_print_term (FILE *file, omega_pb pb, eqn e, int c)
  127. {
  128. int i;
  129. bool first = true;
  130. int n = pb->num_vars;
  131. int went_first = -1;
  132. for (i = 1; i <= n; i++)
  133. if (c * e->coef[i] > 0)
  134. {
  135. first = false;
  136. went_first = i;
  137. if (c * e->coef[i] == 1)
  138. fprintf (file, "%s", omega_variable_to_str (pb, i));
  139. else
  140. fprintf (file, "%d * %s", c * e->coef[i],
  141. omega_variable_to_str (pb, i));
  142. break;
  143. }
  144. for (i = 1; i <= n; i++)
  145. if (i != went_first && c * e->coef[i] != 0)
  146. {
  147. if (!first && c * e->coef[i] > 0)
  148. fprintf (file, " + ");
  149. first = false;
  150. if (c * e->coef[i] == 1)
  151. fprintf (file, "%s", omega_variable_to_str (pb, i));
  152. else if (c * e->coef[i] == -1)
  153. fprintf (file, " - %s", omega_variable_to_str (pb, i));
  154. else
  155. fprintf (file, "%d * %s", c * e->coef[i],
  156. omega_variable_to_str (pb, i));
  157. }
  158. if (!first && c * e->coef[0] > 0)
  159. fprintf (file, " + ");
  160. if (first || c * e->coef[0] != 0)
  161. fprintf (file, "%d", c * e->coef[0]);
  162. }
  163. /* Print to FILE the equation E of problem PB. */
  164. void
  165. omega_print_eqn (FILE *file, omega_pb pb, eqn e, bool test, int extra)
  166. {
  167. int i;
  168. int n = pb->num_vars + extra;
  169. bool is_lt = test && e->coef[0] == -1;
  170. bool first;
  171. if (test)
  172. {
  173. if (e->touched)
  174. fprintf (file, "!");
  175. else if (e->key != 0)
  176. fprintf (file, "%d: ", e->key);
  177. }
  178. if (e->color == omega_red)
  179. fprintf (file, "[");
  180. first = true;
  181. for (i = is_lt ? 1 : 0; i <= n; i++)
  182. if (e->coef[i] < 0)
  183. {
  184. if (!first)
  185. fprintf (file, " + ");
  186. else
  187. first = false;
  188. if (i == 0)
  189. fprintf (file, "%d", -e->coef[i]);
  190. else if (e->coef[i] == -1)
  191. fprintf (file, "%s", omega_variable_to_str (pb, i));
  192. else
  193. fprintf (file, "%d * %s", -e->coef[i],
  194. omega_variable_to_str (pb, i));
  195. }
  196. if (first)
  197. {
  198. if (is_lt)
  199. {
  200. fprintf (file, "1");
  201. is_lt = false;
  202. }
  203. else
  204. fprintf (file, "0");
  205. }
  206. if (test == 0)
  207. fprintf (file, " = ");
  208. else if (is_lt)
  209. fprintf (file, " < ");
  210. else
  211. fprintf (file, " <= ");
  212. first = true;
  213. for (i = 0; i <= n; i++)
  214. if (e->coef[i] > 0)
  215. {
  216. if (!first)
  217. fprintf (file, " + ");
  218. else
  219. first = false;
  220. if (i == 0)
  221. fprintf (file, "%d", e->coef[i]);
  222. else if (e->coef[i] == 1)
  223. fprintf (file, "%s", omega_variable_to_str (pb, i));
  224. else
  225. fprintf (file, "%d * %s", e->coef[i],
  226. omega_variable_to_str (pb, i));
  227. }
  228. if (first)
  229. fprintf (file, "0");
  230. if (e->color == omega_red)
  231. fprintf (file, "]");
  232. }
  233. /* Print to FILE all the variables of problem PB. */
  234. static void
  235. omega_print_vars (FILE *file, omega_pb pb)
  236. {
  237. int i;
  238. fprintf (file, "variables = ");
  239. if (pb->safe_vars > 0)
  240. fprintf (file, "protected (");
  241. for (i = 1; i <= pb->num_vars; i++)
  242. {
  243. fprintf (file, "%s", omega_variable_to_str (pb, i));
  244. if (i == pb->safe_vars)
  245. fprintf (file, ")");
  246. if (i < pb->num_vars)
  247. fprintf (file, ", ");
  248. }
  249. fprintf (file, "\n");
  250. }
  251. /* Dump problem PB. */
  252. DEBUG_FUNCTION void
  253. debug (omega_pb_d &ref)
  254. {
  255. omega_print_problem (stderr, &ref);
  256. }
  257. DEBUG_FUNCTION void
  258. debug (omega_pb_d *ptr)
  259. {
  260. if (ptr)
  261. debug (*ptr);
  262. else
  263. fprintf (stderr, "<nil>\n");
  264. }
  265. /* Debug problem PB. */
  266. DEBUG_FUNCTION void
  267. debug_omega_problem (omega_pb pb)
  268. {
  269. omega_print_problem (stderr, pb);
  270. }
  271. /* Print to FILE problem PB. */
  272. void
  273. omega_print_problem (FILE *file, omega_pb pb)
  274. {
  275. int e;
  276. if (!pb->variables_initialized)
  277. omega_initialize_variables (pb);
  278. omega_print_vars (file, pb);
  279. for (e = 0; e < pb->num_eqs; e++)
  280. {
  281. omega_print_eq (file, pb, &pb->eqs[e]);
  282. fprintf (file, "\n");
  283. }
  284. fprintf (file, "Done with EQ\n");
  285. for (e = 0; e < pb->num_geqs; e++)
  286. {
  287. omega_print_geq (file, pb, &pb->geqs[e]);
  288. fprintf (file, "\n");
  289. }
  290. fprintf (file, "Done with GEQ\n");
  291. for (e = 0; e < pb->num_subs; e++)
  292. {
  293. eqn eq = &pb->subs[e];
  294. if (eq->color == omega_red)
  295. fprintf (file, "[");
  296. if (eq->key > 0)
  297. fprintf (file, "%s := ", omega_var_to_str (eq->key));
  298. else
  299. fprintf (file, "#%d := ", eq->key);
  300. omega_print_term (file, pb, eq, 1);
  301. if (eq->color == omega_red)
  302. fprintf (file, "]");
  303. fprintf (file, "\n");
  304. }
  305. }
  306. /* Return the number of equations in PB tagged omega_red. */
  307. int
  308. omega_count_red_equations (omega_pb pb)
  309. {
  310. int e, i;
  311. int result = 0;
  312. for (e = 0; e < pb->num_eqs; e++)
  313. if (pb->eqs[e].color == omega_red)
  314. {
  315. for (i = pb->num_vars; i > 0; i--)
  316. if (pb->geqs[e].coef[i])
  317. break;
  318. if (i == 0 && pb->geqs[e].coef[0] == 1)
  319. return 0;
  320. else
  321. result += 2;
  322. }
  323. for (e = 0; e < pb->num_geqs; e++)
  324. if (pb->geqs[e].color == omega_red)
  325. result += 1;
  326. for (e = 0; e < pb->num_subs; e++)
  327. if (pb->subs[e].color == omega_red)
  328. result += 2;
  329. return result;
  330. }
  331. /* Print to FILE all the equations in PB that are tagged omega_red. */
  332. void
  333. omega_print_red_equations (FILE *file, omega_pb pb)
  334. {
  335. int e;
  336. if (!pb->variables_initialized)
  337. omega_initialize_variables (pb);
  338. omega_print_vars (file, pb);
  339. for (e = 0; e < pb->num_eqs; e++)
  340. if (pb->eqs[e].color == omega_red)
  341. {
  342. omega_print_eq (file, pb, &pb->eqs[e]);
  343. fprintf (file, "\n");
  344. }
  345. for (e = 0; e < pb->num_geqs; e++)
  346. if (pb->geqs[e].color == omega_red)
  347. {
  348. omega_print_geq (file, pb, &pb->geqs[e]);
  349. fprintf (file, "\n");
  350. }
  351. for (e = 0; e < pb->num_subs; e++)
  352. if (pb->subs[e].color == omega_red)
  353. {
  354. eqn eq = &pb->subs[e];
  355. fprintf (file, "[");
  356. if (eq->key > 0)
  357. fprintf (file, "%s := ", omega_var_to_str (eq->key));
  358. else
  359. fprintf (file, "#%d := ", eq->key);
  360. omega_print_term (file, pb, eq, 1);
  361. fprintf (file, "]\n");
  362. }
  363. }
  364. /* Pretty print PB to FILE. */
  365. void
  366. omega_pretty_print_problem (FILE *file, omega_pb pb)
  367. {
  368. int e, v, v1, v2, v3, t;
  369. bool *live = XNEWVEC (bool, OMEGA_MAX_GEQS);
  370. int stuffPrinted = 0;
  371. bool change;
  372. typedef enum {
  373. none, le, lt
  374. } partial_order_type;
  375. partial_order_type **po = XNEWVEC (partial_order_type *,
  376. OMEGA_MAX_VARS * OMEGA_MAX_VARS);
  377. int **po_eq = XNEWVEC (int *, OMEGA_MAX_VARS * OMEGA_MAX_VARS);
  378. int *last_links = XNEWVEC (int, OMEGA_MAX_VARS);
  379. int *first_links = XNEWVEC (int, OMEGA_MAX_VARS);
  380. int *chain_length = XNEWVEC (int, OMEGA_MAX_VARS);
  381. int *chain = XNEWVEC (int, OMEGA_MAX_VARS);
  382. int i, m;
  383. bool multiprint;
  384. if (!pb->variables_initialized)
  385. omega_initialize_variables (pb);
  386. if (pb->num_vars > 0)
  387. {
  388. omega_eliminate_redundant (pb, false);
  389. for (e = 0; e < pb->num_eqs; e++)
  390. {
  391. if (stuffPrinted)
  392. fprintf (file, "; ");
  393. stuffPrinted = 1;
  394. omega_print_eq (file, pb, &pb->eqs[e]);
  395. }
  396. for (e = 0; e < pb->num_geqs; e++)
  397. live[e] = true;
  398. while (1)
  399. {
  400. for (v = 1; v <= pb->num_vars; v++)
  401. {
  402. last_links[v] = first_links[v] = 0;
  403. chain_length[v] = 0;
  404. for (v2 = 1; v2 <= pb->num_vars; v2++)
  405. po[v][v2] = none;
  406. }
  407. for (e = 0; e < pb->num_geqs; e++)
  408. if (live[e])
  409. {
  410. for (v = 1; v <= pb->num_vars; v++)
  411. if (pb->geqs[e].coef[v] == 1)
  412. first_links[v]++;
  413. else if (pb->geqs[e].coef[v] == -1)
  414. last_links[v]++;
  415. v1 = pb->num_vars;
  416. while (v1 > 0 && pb->geqs[e].coef[v1] == 0)
  417. v1--;
  418. v2 = v1 - 1;
  419. while (v2 > 0 && pb->geqs[e].coef[v2] == 0)
  420. v2--;
  421. v3 = v2 - 1;
  422. while (v3 > 0 && pb->geqs[e].coef[v3] == 0)
  423. v3--;
  424. if (pb->geqs[e].coef[0] > 0 || pb->geqs[e].coef[0] < -1
  425. || v2 <= 0 || v3 > 0
  426. || pb->geqs[e].coef[v1] * pb->geqs[e].coef[v2] != -1)
  427. {
  428. /* Not a partial order relation. */
  429. }
  430. else
  431. {
  432. if (pb->geqs[e].coef[v1] == 1)
  433. {
  434. v3 = v2;
  435. v2 = v1;
  436. v1 = v3;
  437. }
  438. /* Relation is v1 <= v2 or v1 < v2. */
  439. po[v1][v2] = ((pb->geqs[e].coef[0] == 0) ? le : lt);
  440. po_eq[v1][v2] = e;
  441. }
  442. }
  443. for (v = 1; v <= pb->num_vars; v++)
  444. chain_length[v] = last_links[v];
  445. /* Just in case pb->num_vars <= 0. */
  446. change = false;
  447. for (t = 0; t < pb->num_vars; t++)
  448. {
  449. change = false;
  450. for (v1 = 1; v1 <= pb->num_vars; v1++)
  451. for (v2 = 1; v2 <= pb->num_vars; v2++)
  452. if (po[v1][v2] != none &&
  453. chain_length[v1] <= chain_length[v2])
  454. {
  455. chain_length[v1] = chain_length[v2] + 1;
  456. change = true;
  457. }
  458. }
  459. /* Caught in cycle. */
  460. gcc_assert (!change);
  461. for (v1 = 1; v1 <= pb->num_vars; v1++)
  462. if (chain_length[v1] == 0)
  463. first_links[v1] = 0;
  464. v = 1;
  465. for (v1 = 2; v1 <= pb->num_vars; v1++)
  466. if (chain_length[v1] + first_links[v1] >
  467. chain_length[v] + first_links[v])
  468. v = v1;
  469. if (chain_length[v] + first_links[v] == 0)
  470. break;
  471. if (stuffPrinted)
  472. fprintf (file, "; ");
  473. stuffPrinted = 1;
  474. /* Chain starts at v. */
  475. {
  476. int tmp;
  477. bool first = true;
  478. for (e = 0; e < pb->num_geqs; e++)
  479. if (live[e] && pb->geqs[e].coef[v] == 1)
  480. {
  481. if (!first)
  482. fprintf (file, ", ");
  483. tmp = pb->geqs[e].coef[v];
  484. pb->geqs[e].coef[v] = 0;
  485. omega_print_term (file, pb, &pb->geqs[e], -1);
  486. pb->geqs[e].coef[v] = tmp;
  487. live[e] = false;
  488. first = false;
  489. }
  490. if (!first)
  491. fprintf (file, " <= ");
  492. }
  493. /* Find chain. */
  494. chain[0] = v;
  495. m = 1;
  496. while (1)
  497. {
  498. /* Print chain. */
  499. for (v2 = 1; v2 <= pb->num_vars; v2++)
  500. if (po[v][v2] && chain_length[v] == 1 + chain_length[v2])
  501. break;
  502. if (v2 > pb->num_vars)
  503. break;
  504. chain[m++] = v2;
  505. v = v2;
  506. }
  507. fprintf (file, "%s", omega_variable_to_str (pb, chain[0]));
  508. for (multiprint = false, i = 1; i < m; i++)
  509. {
  510. v = chain[i - 1];
  511. v2 = chain[i];
  512. if (po[v][v2] == le)
  513. fprintf (file, " <= ");
  514. else
  515. fprintf (file, " < ");
  516. fprintf (file, "%s", omega_variable_to_str (pb, v2));
  517. live[po_eq[v][v2]] = false;
  518. if (!multiprint && i < m - 1)
  519. for (v3 = 1; v3 <= pb->num_vars; v3++)
  520. {
  521. if (v == v3 || v2 == v3
  522. || po[v][v2] != po[v][v3]
  523. || po[v2][chain[i + 1]] != po[v3][chain[i + 1]])
  524. continue;
  525. fprintf (file, ",%s", omega_variable_to_str (pb, v3));
  526. live[po_eq[v][v3]] = false;
  527. live[po_eq[v3][chain[i + 1]]] = false;
  528. multiprint = true;
  529. }
  530. else
  531. multiprint = false;
  532. }
  533. v = chain[m - 1];
  534. /* Print last_links. */
  535. {
  536. int tmp;
  537. bool first = true;
  538. for (e = 0; e < pb->num_geqs; e++)
  539. if (live[e] && pb->geqs[e].coef[v] == -1)
  540. {
  541. if (!first)
  542. fprintf (file, ", ");
  543. else
  544. fprintf (file, " <= ");
  545. tmp = pb->geqs[e].coef[v];
  546. pb->geqs[e].coef[v] = 0;
  547. omega_print_term (file, pb, &pb->geqs[e], 1);
  548. pb->geqs[e].coef[v] = tmp;
  549. live[e] = false;
  550. first = false;
  551. }
  552. }
  553. }
  554. for (e = 0; e < pb->num_geqs; e++)
  555. if (live[e])
  556. {
  557. if (stuffPrinted)
  558. fprintf (file, "; ");
  559. stuffPrinted = 1;
  560. omega_print_geq (file, pb, &pb->geqs[e]);
  561. }
  562. for (e = 0; e < pb->num_subs; e++)
  563. {
  564. eqn eq = &pb->subs[e];
  565. if (stuffPrinted)
  566. fprintf (file, "; ");
  567. stuffPrinted = 1;
  568. if (eq->key > 0)
  569. fprintf (file, "%s := ", omega_var_to_str (eq->key));
  570. else
  571. fprintf (file, "#%d := ", eq->key);
  572. omega_print_term (file, pb, eq, 1);
  573. }
  574. }
  575. free (live);
  576. free (po);
  577. free (po_eq);
  578. free (last_links);
  579. free (first_links);
  580. free (chain_length);
  581. free (chain);
  582. }
  583. /* Assign to variable I in PB the next wildcard name. The name of a
  584. wildcard is a negative number. */
  585. static int next_wild_card = 0;
  586. static void
  587. omega_name_wild_card (omega_pb pb, int i)
  588. {
  589. --next_wild_card;
  590. if (next_wild_card < -PARAM_VALUE (PARAM_OMEGA_MAX_WILD_CARDS))
  591. next_wild_card = -1;
  592. pb->var[i] = next_wild_card;
  593. }
  594. /* Return the index of the last protected (or safe) variable in PB,
  595. after having added a new wildcard variable. */
  596. static int
  597. omega_add_new_wild_card (omega_pb pb)
  598. {
  599. int e;
  600. int i = ++pb->safe_vars;
  601. pb->num_vars++;
  602. /* Make a free place in the protected (safe) variables, by moving
  603. the non protected variable pointed by "I" at the end, ie. at
  604. offset pb->num_vars. */
  605. if (pb->num_vars != i)
  606. {
  607. /* Move "I" for all the inequalities. */
  608. for (e = pb->num_geqs - 1; e >= 0; e--)
  609. {
  610. if (pb->geqs[e].coef[i])
  611. pb->geqs[e].touched = 1;
  612. pb->geqs[e].coef[pb->num_vars] = pb->geqs[e].coef[i];
  613. }
  614. /* Move "I" for all the equalities. */
  615. for (e = pb->num_eqs - 1; e >= 0; e--)
  616. pb->eqs[e].coef[pb->num_vars] = pb->eqs[e].coef[i];
  617. /* Move "I" for all the substitutions. */
  618. for (e = pb->num_subs - 1; e >= 0; e--)
  619. pb->subs[e].coef[pb->num_vars] = pb->subs[e].coef[i];
  620. /* Move the identifier. */
  621. pb->var[pb->num_vars] = pb->var[i];
  622. }
  623. /* Initialize at zero all the coefficients */
  624. for (e = pb->num_geqs - 1; e >= 0; e--)
  625. pb->geqs[e].coef[i] = 0;
  626. for (e = pb->num_eqs - 1; e >= 0; e--)
  627. pb->eqs[e].coef[i] = 0;
  628. for (e = pb->num_subs - 1; e >= 0; e--)
  629. pb->subs[e].coef[i] = 0;
  630. /* And give it a name. */
  631. omega_name_wild_card (pb, i);
  632. return i;
  633. }
  634. /* Delete inequality E from problem PB that has N_VARS variables. */
  635. static void
  636. omega_delete_geq (omega_pb pb, int e, int n_vars)
  637. {
  638. if (dump_file && (dump_flags & TDF_DETAILS))
  639. {
  640. fprintf (dump_file, "Deleting %d (last:%d): ", e, pb->num_geqs - 1);
  641. omega_print_geq (dump_file, pb, &pb->geqs[e]);
  642. fprintf (dump_file, "\n");
  643. }
  644. if (e < pb->num_geqs - 1)
  645. omega_copy_eqn (&pb->geqs[e], &pb->geqs[pb->num_geqs - 1], n_vars);
  646. pb->num_geqs--;
  647. }
  648. /* Delete extra inequality E from problem PB that has N_VARS
  649. variables. */
  650. static void
  651. omega_delete_geq_extra (omega_pb pb, int e, int n_vars)
  652. {
  653. if (dump_file && (dump_flags & TDF_DETAILS))
  654. {
  655. fprintf (dump_file, "Deleting %d: ",e);
  656. omega_print_geq_extra (dump_file, pb, &pb->geqs[e]);
  657. fprintf (dump_file, "\n");
  658. }
  659. if (e < pb->num_geqs - 1)
  660. omega_copy_eqn (&pb->geqs[e], &pb->geqs[pb->num_geqs - 1], n_vars);
  661. pb->num_geqs--;
  662. }
  663. /* Remove variable I from problem PB. */
  664. static void
  665. omega_delete_variable (omega_pb pb, int i)
  666. {
  667. int n_vars = pb->num_vars;
  668. int e;
  669. if (omega_safe_var_p (pb, i))
  670. {
  671. int j = pb->safe_vars;
  672. for (e = pb->num_geqs - 1; e >= 0; e--)
  673. {
  674. pb->geqs[e].touched = 1;
  675. pb->geqs[e].coef[i] = pb->geqs[e].coef[j];
  676. pb->geqs[e].coef[j] = pb->geqs[e].coef[n_vars];
  677. }
  678. for (e = pb->num_eqs - 1; e >= 0; e--)
  679. {
  680. pb->eqs[e].coef[i] = pb->eqs[e].coef[j];
  681. pb->eqs[e].coef[j] = pb->eqs[e].coef[n_vars];
  682. }
  683. for (e = pb->num_subs - 1; e >= 0; e--)
  684. {
  685. pb->subs[e].coef[i] = pb->subs[e].coef[j];
  686. pb->subs[e].coef[j] = pb->subs[e].coef[n_vars];
  687. }
  688. pb->var[i] = pb->var[j];
  689. pb->var[j] = pb->var[n_vars];
  690. }
  691. else if (i < n_vars)
  692. {
  693. for (e = pb->num_geqs - 1; e >= 0; e--)
  694. if (pb->geqs[e].coef[n_vars])
  695. {
  696. pb->geqs[e].coef[i] = pb->geqs[e].coef[n_vars];
  697. pb->geqs[e].touched = 1;
  698. }
  699. for (e = pb->num_eqs - 1; e >= 0; e--)
  700. pb->eqs[e].coef[i] = pb->eqs[e].coef[n_vars];
  701. for (e = pb->num_subs - 1; e >= 0; e--)
  702. pb->subs[e].coef[i] = pb->subs[e].coef[n_vars];
  703. pb->var[i] = pb->var[n_vars];
  704. }
  705. if (omega_safe_var_p (pb, i))
  706. pb->safe_vars--;
  707. pb->num_vars--;
  708. }
  709. /* Because the coefficients of an equation are sparse, PACKING records
  710. indices for non null coefficients. */
  711. static int *packing;
  712. /* Set up the coefficients of PACKING, following the coefficients of
  713. equation EQN that has NUM_VARS variables. */
  714. static inline int
  715. setup_packing (eqn eqn, int num_vars)
  716. {
  717. int k;
  718. int n = 0;
  719. for (k = num_vars; k >= 0; k--)
  720. if (eqn->coef[k])
  721. packing[n++] = k;
  722. return n;
  723. }
  724. /* Computes a linear combination of EQ and SUB at VAR with coefficient
  725. C, such that EQ->coef[VAR] is set to 0. TOP_VAR is the number of
  726. non null indices of SUB stored in PACKING. */
  727. static inline void
  728. omega_substitute_red_1 (eqn eq, eqn sub, int var, int c, bool *found_black,
  729. int top_var)
  730. {
  731. if (eq->coef[var] != 0)
  732. {
  733. if (eq->color == omega_black)
  734. *found_black = true;
  735. else
  736. {
  737. int j, k = eq->coef[var];
  738. eq->coef[var] = 0;
  739. for (j = top_var; j >= 0; j--)
  740. eq->coef[packing[j]] -= sub->coef[packing[j]] * k * c;
  741. }
  742. }
  743. }
  744. /* Substitute in PB variable VAR with "C * SUB". */
  745. static void
  746. omega_substitute_red (omega_pb pb, eqn sub, int var, int c, bool *found_black)
  747. {
  748. int e, top_var = setup_packing (sub, pb->num_vars);
  749. *found_black = false;
  750. if (dump_file && (dump_flags & TDF_DETAILS))
  751. {
  752. if (sub->color == omega_red)
  753. fprintf (dump_file, "[");
  754. fprintf (dump_file, "substituting using %s := ",
  755. omega_variable_to_str (pb, var));
  756. omega_print_term (dump_file, pb, sub, -c);
  757. if (sub->color == omega_red)
  758. fprintf (dump_file, "]");
  759. fprintf (dump_file, "\n");
  760. omega_print_vars (dump_file, pb);
  761. }
  762. for (e = pb->num_eqs - 1; e >= 0; e--)
  763. {
  764. eqn eqn = &(pb->eqs[e]);
  765. omega_substitute_red_1 (eqn, sub, var, c, found_black, top_var);
  766. if (dump_file && (dump_flags & TDF_DETAILS))
  767. {
  768. omega_print_eq (dump_file, pb, eqn);
  769. fprintf (dump_file, "\n");
  770. }
  771. }
  772. for (e = pb->num_geqs - 1; e >= 0; e--)
  773. {
  774. eqn eqn = &(pb->geqs[e]);
  775. omega_substitute_red_1 (eqn, sub, var, c, found_black, top_var);
  776. if (eqn->coef[var] && eqn->color == omega_red)
  777. eqn->touched = 1;
  778. if (dump_file && (dump_flags & TDF_DETAILS))
  779. {
  780. omega_print_geq (dump_file, pb, eqn);
  781. fprintf (dump_file, "\n");
  782. }
  783. }
  784. for (e = pb->num_subs - 1; e >= 0; e--)
  785. {
  786. eqn eqn = &(pb->subs[e]);
  787. omega_substitute_red_1 (eqn, sub, var, c, found_black, top_var);
  788. if (dump_file && (dump_flags & TDF_DETAILS))
  789. {
  790. fprintf (dump_file, "%s := ", omega_var_to_str (eqn->key));
  791. omega_print_term (dump_file, pb, eqn, 1);
  792. fprintf (dump_file, "\n");
  793. }
  794. }
  795. if (dump_file && (dump_flags & TDF_DETAILS))
  796. fprintf (dump_file, "---\n\n");
  797. if (omega_safe_var_p (pb, var) && !omega_wildcard_p (pb, var))
  798. *found_black = true;
  799. }
  800. /* Substitute in PB variable VAR with "C * SUB". */
  801. static void
  802. omega_substitute (omega_pb pb, eqn sub, int var, int c)
  803. {
  804. int e, j, j0;
  805. int top_var = setup_packing (sub, pb->num_vars);
  806. if (dump_file && (dump_flags & TDF_DETAILS))
  807. {
  808. fprintf (dump_file, "substituting using %s := ",
  809. omega_variable_to_str (pb, var));
  810. omega_print_term (dump_file, pb, sub, -c);
  811. fprintf (dump_file, "\n");
  812. omega_print_vars (dump_file, pb);
  813. }
  814. if (top_var < 0)
  815. {
  816. for (e = pb->num_eqs - 1; e >= 0; e--)
  817. pb->eqs[e].coef[var] = 0;
  818. for (e = pb->num_geqs - 1; e >= 0; e--)
  819. if (pb->geqs[e].coef[var] != 0)
  820. {
  821. pb->geqs[e].touched = 1;
  822. pb->geqs[e].coef[var] = 0;
  823. }
  824. for (e = pb->num_subs - 1; e >= 0; e--)
  825. pb->subs[e].coef[var] = 0;
  826. if (omega_safe_var_p (pb, var) && !omega_wildcard_p (pb, var))
  827. {
  828. int k;
  829. eqn eqn = &(pb->subs[pb->num_subs++]);
  830. for (k = pb->num_vars; k >= 0; k--)
  831. eqn->coef[k] = 0;
  832. eqn->key = pb->var[var];
  833. eqn->color = omega_black;
  834. }
  835. }
  836. else if (top_var == 0 && packing[0] == 0)
  837. {
  838. c = -sub->coef[0] * c;
  839. for (e = pb->num_eqs - 1; e >= 0; e--)
  840. {
  841. pb->eqs[e].coef[0] += pb->eqs[e].coef[var] * c;
  842. pb->eqs[e].coef[var] = 0;
  843. }
  844. for (e = pb->num_geqs - 1; e >= 0; e--)
  845. if (pb->geqs[e].coef[var] != 0)
  846. {
  847. pb->geqs[e].coef[0] += pb->geqs[e].coef[var] * c;
  848. pb->geqs[e].coef[var] = 0;
  849. pb->geqs[e].touched = 1;
  850. }
  851. for (e = pb->num_subs - 1; e >= 0; e--)
  852. {
  853. pb->subs[e].coef[0] += pb->subs[e].coef[var] * c;
  854. pb->subs[e].coef[var] = 0;
  855. }
  856. if (omega_safe_var_p (pb, var) && !omega_wildcard_p (pb, var))
  857. {
  858. int k;
  859. eqn eqn = &(pb->subs[pb->num_subs++]);
  860. for (k = pb->num_vars; k >= 1; k--)
  861. eqn->coef[k] = 0;
  862. eqn->coef[0] = c;
  863. eqn->key = pb->var[var];
  864. eqn->color = omega_black;
  865. }
  866. if (dump_file && (dump_flags & TDF_DETAILS))
  867. {
  868. fprintf (dump_file, "---\n\n");
  869. omega_print_problem (dump_file, pb);
  870. fprintf (dump_file, "===\n\n");
  871. }
  872. }
  873. else
  874. {
  875. for (e = pb->num_eqs - 1; e >= 0; e--)
  876. {
  877. eqn eqn = &(pb->eqs[e]);
  878. int k = eqn->coef[var];
  879. if (k != 0)
  880. {
  881. k = c * k;
  882. eqn->coef[var] = 0;
  883. for (j = top_var; j >= 0; j--)
  884. {
  885. j0 = packing[j];
  886. eqn->coef[j0] -= sub->coef[j0] * k;
  887. }
  888. }
  889. if (dump_file && (dump_flags & TDF_DETAILS))
  890. {
  891. omega_print_eq (dump_file, pb, eqn);
  892. fprintf (dump_file, "\n");
  893. }
  894. }
  895. for (e = pb->num_geqs - 1; e >= 0; e--)
  896. {
  897. eqn eqn = &(pb->geqs[e]);
  898. int k = eqn->coef[var];
  899. if (k != 0)
  900. {
  901. k = c * k;
  902. eqn->touched = 1;
  903. eqn->coef[var] = 0;
  904. for (j = top_var; j >= 0; j--)
  905. {
  906. j0 = packing[j];
  907. eqn->coef[j0] -= sub->coef[j0] * k;
  908. }
  909. }
  910. if (dump_file && (dump_flags & TDF_DETAILS))
  911. {
  912. omega_print_geq (dump_file, pb, eqn);
  913. fprintf (dump_file, "\n");
  914. }
  915. }
  916. for (e = pb->num_subs - 1; e >= 0; e--)
  917. {
  918. eqn eqn = &(pb->subs[e]);
  919. int k = eqn->coef[var];
  920. if (k != 0)
  921. {
  922. k = c * k;
  923. eqn->coef[var] = 0;
  924. for (j = top_var; j >= 0; j--)
  925. {
  926. j0 = packing[j];
  927. eqn->coef[j0] -= sub->coef[j0] * k;
  928. }
  929. }
  930. if (dump_file && (dump_flags & TDF_DETAILS))
  931. {
  932. fprintf (dump_file, "%s := ", omega_var_to_str (eqn->key));
  933. omega_print_term (dump_file, pb, eqn, 1);
  934. fprintf (dump_file, "\n");
  935. }
  936. }
  937. if (dump_file && (dump_flags & TDF_DETAILS))
  938. {
  939. fprintf (dump_file, "---\n\n");
  940. omega_print_problem (dump_file, pb);
  941. fprintf (dump_file, "===\n\n");
  942. }
  943. if (omega_safe_var_p (pb, var) && !omega_wildcard_p (pb, var))
  944. {
  945. int k;
  946. eqn eqn = &(pb->subs[pb->num_subs++]);
  947. c = -c;
  948. for (k = pb->num_vars; k >= 0; k--)
  949. eqn->coef[k] = c * (sub->coef[k]);
  950. eqn->key = pb->var[var];
  951. eqn->color = sub->color;
  952. }
  953. }
  954. }
  955. /* Solve e = factor alpha for x_j and substitute. */
  956. static void
  957. omega_do_mod (omega_pb pb, int factor, int e, int j)
  958. {
  959. int k, i;
  960. eqn eq = omega_alloc_eqns (0, 1);
  961. int nfactor;
  962. bool kill_j = false;
  963. omega_copy_eqn (eq, &pb->eqs[e], pb->num_vars);
  964. for (k = pb->num_vars; k >= 0; k--)
  965. {
  966. eq->coef[k] = int_mod (eq->coef[k], factor);
  967. if (2 * eq->coef[k] >= factor)
  968. eq->coef[k] -= factor;
  969. }
  970. nfactor = eq->coef[j];
  971. if (omega_safe_var_p (pb, j) && !omega_wildcard_p (pb, j))
  972. {
  973. i = omega_add_new_wild_card (pb);
  974. eq->coef[pb->num_vars] = eq->coef[i];
  975. eq->coef[j] = 0;
  976. eq->coef[i] = -factor;
  977. kill_j = true;
  978. }
  979. else
  980. {
  981. eq->coef[j] = -factor;
  982. if (!omega_wildcard_p (pb, j))
  983. omega_name_wild_card (pb, j);
  984. }
  985. omega_substitute (pb, eq, j, nfactor);
  986. for (k = pb->num_vars; k >= 0; k--)
  987. pb->eqs[e].coef[k] = pb->eqs[e].coef[k] / factor;
  988. if (kill_j)
  989. omega_delete_variable (pb, j);
  990. if (dump_file && (dump_flags & TDF_DETAILS))
  991. {
  992. fprintf (dump_file, "Mod-ing and normalizing produces:\n");
  993. omega_print_problem (dump_file, pb);
  994. }
  995. omega_free_eqns (eq, 1);
  996. }
  997. /* Multiplies by -1 inequality E. */
  998. void
  999. omega_negate_geq (omega_pb pb, int e)
  1000. {
  1001. int i;
  1002. for (i = pb->num_vars; i >= 0; i--)
  1003. pb->geqs[e].coef[i] *= -1;
  1004. pb->geqs[e].coef[0]--;
  1005. pb->geqs[e].touched = 1;
  1006. }
  1007. /* Returns OMEGA_TRUE when problem PB has a solution. */
  1008. static enum omega_result
  1009. verify_omega_pb (omega_pb pb)
  1010. {
  1011. enum omega_result result;
  1012. int e;
  1013. bool any_color = false;
  1014. omega_pb tmp_problem = XNEW (struct omega_pb_d);
  1015. omega_copy_problem (tmp_problem, pb);
  1016. tmp_problem->safe_vars = 0;
  1017. tmp_problem->num_subs = 0;
  1018. for (e = pb->num_geqs - 1; e >= 0; e--)
  1019. if (pb->geqs[e].color == omega_red)
  1020. {
  1021. any_color = true;
  1022. break;
  1023. }
  1024. if (please_no_equalities_in_simplified_problems)
  1025. any_color = true;
  1026. if (any_color)
  1027. original_problem = no_problem;
  1028. else
  1029. original_problem = pb;
  1030. if (dump_file && (dump_flags & TDF_DETAILS))
  1031. {
  1032. fprintf (dump_file, "verifying problem");
  1033. if (any_color)
  1034. fprintf (dump_file, " (color mode)");
  1035. fprintf (dump_file, " :\n");
  1036. omega_print_problem (dump_file, pb);
  1037. }
  1038. result = omega_solve_problem (tmp_problem, omega_unknown);
  1039. original_problem = no_problem;
  1040. free (tmp_problem);
  1041. if (dump_file && (dump_flags & TDF_DETAILS))
  1042. {
  1043. if (result != omega_false)
  1044. fprintf (dump_file, "verified problem\n");
  1045. else
  1046. fprintf (dump_file, "disproved problem\n");
  1047. omega_print_problem (dump_file, pb);
  1048. }
  1049. return result;
  1050. }
  1051. /* Add a new equality to problem PB at last position E. */
  1052. static void
  1053. adding_equality_constraint (omega_pb pb, int e)
  1054. {
  1055. if (original_problem != no_problem
  1056. && original_problem != pb
  1057. && !conservative)
  1058. {
  1059. int i, j;
  1060. int e2 = original_problem->num_eqs++;
  1061. if (dump_file && (dump_flags & TDF_DETAILS))
  1062. fprintf (dump_file,
  1063. "adding equality constraint %d to outer problem\n", e2);
  1064. omega_init_eqn_zero (&original_problem->eqs[e2],
  1065. original_problem->num_vars);
  1066. for (i = pb->num_vars; i >= 1; i--)
  1067. {
  1068. for (j = original_problem->num_vars; j >= 1; j--)
  1069. if (original_problem->var[j] == pb->var[i])
  1070. break;
  1071. if (j <= 0)
  1072. {
  1073. if (dump_file && (dump_flags & TDF_DETAILS))
  1074. fprintf (dump_file, "retracting\n");
  1075. original_problem->num_eqs--;
  1076. return;
  1077. }
  1078. original_problem->eqs[e2].coef[j] = pb->eqs[e].coef[i];
  1079. }
  1080. original_problem->eqs[e2].coef[0] = pb->eqs[e].coef[0];
  1081. if (dump_file && (dump_flags & TDF_DETAILS))
  1082. omega_print_problem (dump_file, original_problem);
  1083. }
  1084. }
  1085. static int *fast_lookup;
  1086. static int *fast_lookup_red;
  1087. typedef enum {
  1088. normalize_false,
  1089. normalize_uncoupled,
  1090. normalize_coupled
  1091. } normalize_return_type;
  1092. /* Normalizes PB by removing redundant constraints. Returns
  1093. normalize_false when the constraints system has no solution,
  1094. otherwise returns normalize_coupled or normalize_uncoupled. */
  1095. static normalize_return_type
  1096. normalize_omega_problem (omega_pb pb)
  1097. {
  1098. int e, i, j, k, n_vars;
  1099. int coupled_subscripts = 0;
  1100. n_vars = pb->num_vars;
  1101. for (e = 0; e < pb->num_geqs; e++)
  1102. {
  1103. if (!pb->geqs[e].touched)
  1104. {
  1105. if (!single_var_geq (&pb->geqs[e], n_vars))
  1106. coupled_subscripts = 1;
  1107. }
  1108. else
  1109. {
  1110. int g, top_var, i0, hashCode;
  1111. int *p = &packing[0];
  1112. for (k = 1; k <= n_vars; k++)
  1113. if (pb->geqs[e].coef[k])
  1114. *(p++) = k;
  1115. top_var = (p - &packing[0]) - 1;
  1116. if (top_var == -1)
  1117. {
  1118. if (pb->geqs[e].coef[0] < 0)
  1119. {
  1120. if (dump_file && (dump_flags & TDF_DETAILS))
  1121. {
  1122. omega_print_geq (dump_file, pb, &pb->geqs[e]);
  1123. fprintf (dump_file, "\nequations have no solution \n");
  1124. }
  1125. return normalize_false;
  1126. }
  1127. omega_delete_geq (pb, e, n_vars);
  1128. e--;
  1129. continue;
  1130. }
  1131. else if (top_var == 0)
  1132. {
  1133. int singlevar = packing[0];
  1134. g = pb->geqs[e].coef[singlevar];
  1135. if (g > 0)
  1136. {
  1137. pb->geqs[e].coef[singlevar] = 1;
  1138. pb->geqs[e].key = singlevar;
  1139. }
  1140. else
  1141. {
  1142. g = -g;
  1143. pb->geqs[e].coef[singlevar] = -1;
  1144. pb->geqs[e].key = -singlevar;
  1145. }
  1146. if (g > 1)
  1147. pb->geqs[e].coef[0] = int_div (pb->geqs[e].coef[0], g);
  1148. }
  1149. else
  1150. {
  1151. int g2;
  1152. int hash_key_multiplier = 31;
  1153. coupled_subscripts = 1;
  1154. i0 = top_var;
  1155. i = packing[i0--];
  1156. g = pb->geqs[e].coef[i];
  1157. hashCode = g * (i + 3);
  1158. if (g < 0)
  1159. g = -g;
  1160. for (; i0 >= 0; i0--)
  1161. {
  1162. int x;
  1163. i = packing[i0];
  1164. x = pb->geqs[e].coef[i];
  1165. hashCode = hashCode * hash_key_multiplier * (i + 3) + x;
  1166. if (x < 0)
  1167. x = -x;
  1168. if (x == 1)
  1169. {
  1170. g = 1;
  1171. i0--;
  1172. break;
  1173. }
  1174. else
  1175. g = gcd (x, g);
  1176. }
  1177. for (; i0 >= 0; i0--)
  1178. {
  1179. int x;
  1180. i = packing[i0];
  1181. x = pb->geqs[e].coef[i];
  1182. hashCode = hashCode * hash_key_multiplier * (i + 3) + x;
  1183. }
  1184. if (g > 1)
  1185. {
  1186. pb->geqs[e].coef[0] = int_div (pb->geqs[e].coef[0], g);
  1187. i0 = top_var;
  1188. i = packing[i0--];
  1189. pb->geqs[e].coef[i] = pb->geqs[e].coef[i] / g;
  1190. hashCode = pb->geqs[e].coef[i] * (i + 3);
  1191. for (; i0 >= 0; i0--)
  1192. {
  1193. i = packing[i0];
  1194. pb->geqs[e].coef[i] = pb->geqs[e].coef[i] / g;
  1195. hashCode = hashCode * hash_key_multiplier * (i + 3)
  1196. + pb->geqs[e].coef[i];
  1197. }
  1198. }
  1199. g2 = abs (hashCode);
  1200. if (dump_file && (dump_flags & TDF_DETAILS))
  1201. {
  1202. fprintf (dump_file, "Hash code = %d, eqn = ", hashCode);
  1203. omega_print_geq (dump_file, pb, &pb->geqs[e]);
  1204. fprintf (dump_file, "\n");
  1205. }
  1206. j = g2 % HASH_TABLE_SIZE;
  1207. do {
  1208. eqn proto = &(hash_master[j]);
  1209. if (proto->touched == g2)
  1210. {
  1211. if (proto->coef[0] == top_var)
  1212. {
  1213. if (hashCode >= 0)
  1214. for (i0 = top_var; i0 >= 0; i0--)
  1215. {
  1216. i = packing[i0];
  1217. if (pb->geqs[e].coef[i] != proto->coef[i])
  1218. break;
  1219. }
  1220. else
  1221. for (i0 = top_var; i0 >= 0; i0--)
  1222. {
  1223. i = packing[i0];
  1224. if (pb->geqs[e].coef[i] != -proto->coef[i])
  1225. break;
  1226. }
  1227. if (i0 < 0)
  1228. {
  1229. if (hashCode >= 0)
  1230. pb->geqs[e].key = proto->key;
  1231. else
  1232. pb->geqs[e].key = -proto->key;
  1233. break;
  1234. }
  1235. }
  1236. }
  1237. else if (proto->touched < 0)
  1238. {
  1239. omega_init_eqn_zero (proto, pb->num_vars);
  1240. if (hashCode >= 0)
  1241. for (i0 = top_var; i0 >= 0; i0--)
  1242. {
  1243. i = packing[i0];
  1244. proto->coef[i] = pb->geqs[e].coef[i];
  1245. }
  1246. else
  1247. for (i0 = top_var; i0 >= 0; i0--)
  1248. {
  1249. i = packing[i0];
  1250. proto->coef[i] = -pb->geqs[e].coef[i];
  1251. }
  1252. proto->coef[0] = top_var;
  1253. proto->touched = g2;
  1254. if (dump_file && (dump_flags & TDF_DETAILS))
  1255. fprintf (dump_file, " constraint key = %d\n",
  1256. next_key);
  1257. proto->key = next_key++;
  1258. /* Too many hash keys generated. */
  1259. gcc_assert (proto->key <= MAX_KEYS);
  1260. if (hashCode >= 0)
  1261. pb->geqs[e].key = proto->key;
  1262. else
  1263. pb->geqs[e].key = -proto->key;
  1264. break;
  1265. }
  1266. j = (j + 1) % HASH_TABLE_SIZE;
  1267. } while (1);
  1268. }
  1269. pb->geqs[e].touched = 0;
  1270. }
  1271. {
  1272. int eKey = pb->geqs[e].key;
  1273. int e2;
  1274. if (e > 0)
  1275. {
  1276. int cTerm = pb->geqs[e].coef[0];
  1277. e2 = fast_lookup[MAX_KEYS - eKey];
  1278. if (e2 < e && pb->geqs[e2].key == -eKey
  1279. && pb->geqs[e2].color == omega_black)
  1280. {
  1281. if (pb->geqs[e2].coef[0] < -cTerm)
  1282. {
  1283. if (dump_file && (dump_flags & TDF_DETAILS))
  1284. {
  1285. omega_print_geq (dump_file, pb, &pb->geqs[e]);
  1286. fprintf (dump_file, "\n");
  1287. omega_print_geq (dump_file, pb, &pb->geqs[e2]);
  1288. fprintf (dump_file,
  1289. "\nequations have no solution \n");
  1290. }
  1291. return normalize_false;
  1292. }
  1293. if (pb->geqs[e2].coef[0] == -cTerm
  1294. && (create_color
  1295. || pb->geqs[e].color == omega_black))
  1296. {
  1297. omega_copy_eqn (&pb->eqs[pb->num_eqs], &pb->geqs[e],
  1298. pb->num_vars);
  1299. if (pb->geqs[e].color == omega_black)
  1300. adding_equality_constraint (pb, pb->num_eqs);
  1301. pb->num_eqs++;
  1302. gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
  1303. }
  1304. }
  1305. e2 = fast_lookup_red[MAX_KEYS - eKey];
  1306. if (e2 < e && pb->geqs[e2].key == -eKey
  1307. && pb->geqs[e2].color == omega_red)
  1308. {
  1309. if (pb->geqs[e2].coef[0] < -cTerm)
  1310. {
  1311. if (dump_file && (dump_flags & TDF_DETAILS))
  1312. {
  1313. omega_print_geq (dump_file, pb, &pb->geqs[e]);
  1314. fprintf (dump_file, "\n");
  1315. omega_print_geq (dump_file, pb, &pb->geqs[e2]);
  1316. fprintf (dump_file,
  1317. "\nequations have no solution \n");
  1318. }
  1319. return normalize_false;
  1320. }
  1321. if (pb->geqs[e2].coef[0] == -cTerm && create_color)
  1322. {
  1323. omega_copy_eqn (&pb->eqs[pb->num_eqs], &pb->geqs[e],
  1324. pb->num_vars);
  1325. pb->eqs[pb->num_eqs].color = omega_red;
  1326. pb->num_eqs++;
  1327. gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
  1328. }
  1329. }
  1330. e2 = fast_lookup[MAX_KEYS + eKey];
  1331. if (e2 < e && pb->geqs[e2].key == eKey
  1332. && pb->geqs[e2].color == omega_black)
  1333. {
  1334. if (pb->geqs[e2].coef[0] > cTerm)
  1335. {
  1336. if (pb->geqs[e].color == omega_black)
  1337. {
  1338. if (dump_file && (dump_flags & TDF_DETAILS))
  1339. {
  1340. fprintf (dump_file,
  1341. "Removing Redundant Equation: ");
  1342. omega_print_geq (dump_file, pb, &(pb->geqs[e2]));
  1343. fprintf (dump_file, "\n");
  1344. fprintf (dump_file,
  1345. "[a] Made Redundant by: ");
  1346. omega_print_geq (dump_file, pb, &(pb->geqs[e]));
  1347. fprintf (dump_file, "\n");
  1348. }
  1349. pb->geqs[e2].coef[0] = cTerm;
  1350. omega_delete_geq (pb, e, n_vars);
  1351. e--;
  1352. continue;
  1353. }
  1354. }
  1355. else
  1356. {
  1357. if (dump_file && (dump_flags & TDF_DETAILS))
  1358. {
  1359. fprintf (dump_file, "Removing Redundant Equation: ");
  1360. omega_print_geq (dump_file, pb, &(pb->geqs[e]));
  1361. fprintf (dump_file, "\n");
  1362. fprintf (dump_file, "[b] Made Redundant by: ");
  1363. omega_print_geq (dump_file, pb, &(pb->geqs[e2]));
  1364. fprintf (dump_file, "\n");
  1365. }
  1366. omega_delete_geq (pb, e, n_vars);
  1367. e--;
  1368. continue;
  1369. }
  1370. }
  1371. e2 = fast_lookup_red[MAX_KEYS + eKey];
  1372. if (e2 < e && pb->geqs[e2].key == eKey
  1373. && pb->geqs[e2].color == omega_red)
  1374. {
  1375. if (pb->geqs[e2].coef[0] >= cTerm)
  1376. {
  1377. if (dump_file && (dump_flags & TDF_DETAILS))
  1378. {
  1379. fprintf (dump_file, "Removing Redundant Equation: ");
  1380. omega_print_geq (dump_file, pb, &(pb->geqs[e2]));
  1381. fprintf (dump_file, "\n");
  1382. fprintf (dump_file, "[c] Made Redundant by: ");
  1383. omega_print_geq (dump_file, pb, &(pb->geqs[e]));
  1384. fprintf (dump_file, "\n");
  1385. }
  1386. pb->geqs[e2].coef[0] = cTerm;
  1387. pb->geqs[e2].color = pb->geqs[e].color;
  1388. }
  1389. else if (pb->geqs[e].color == omega_red)
  1390. {
  1391. if (dump_file && (dump_flags & TDF_DETAILS))
  1392. {
  1393. fprintf (dump_file, "Removing Redundant Equation: ");
  1394. omega_print_geq (dump_file, pb, &(pb->geqs[e]));
  1395. fprintf (dump_file, "\n");
  1396. fprintf (dump_file, "[d] Made Redundant by: ");
  1397. omega_print_geq (dump_file, pb, &(pb->geqs[e2]));
  1398. fprintf (dump_file, "\n");
  1399. }
  1400. }
  1401. omega_delete_geq (pb, e, n_vars);
  1402. e--;
  1403. continue;
  1404. }
  1405. }
  1406. if (pb->geqs[e].color == omega_red)
  1407. fast_lookup_red[MAX_KEYS + eKey] = e;
  1408. else
  1409. fast_lookup[MAX_KEYS + eKey] = e;
  1410. }
  1411. }
  1412. create_color = false;
  1413. return coupled_subscripts ? normalize_coupled : normalize_uncoupled;
  1414. }
  1415. /* Divide the coefficients of EQN by their gcd. N_VARS is the number
  1416. of variables in EQN. */
  1417. static inline void
  1418. divide_eqn_by_gcd (eqn eqn, int n_vars)
  1419. {
  1420. int var, g = 0;
  1421. for (var = n_vars; var >= 0; var--)
  1422. g = gcd (abs (eqn->coef[var]), g);
  1423. if (g)
  1424. for (var = n_vars; var >= 0; var--)
  1425. eqn->coef[var] = eqn->coef[var] / g;
  1426. }
  1427. /* Rewrite some non-safe variables in function of protected
  1428. wildcard variables. */
  1429. static void
  1430. cleanout_wildcards (omega_pb pb)
  1431. {
  1432. int e, i, j;
  1433. int n_vars = pb->num_vars;
  1434. bool renormalize = false;
  1435. for (e = pb->num_eqs - 1; e >= 0; e--)
  1436. for (i = n_vars; !omega_safe_var_p (pb, i); i--)
  1437. if (pb->eqs[e].coef[i] != 0)
  1438. {
  1439. /* i is the last nonzero non-safe variable. */
  1440. for (j = i - 1; !omega_safe_var_p (pb, j); j--)
  1441. if (pb->eqs[e].coef[j] != 0)
  1442. break;
  1443. /* j is the next nonzero non-safe variable, or points
  1444. to a safe variable: it is then a wildcard variable. */
  1445. /* Clean it out. */
  1446. if (omega_safe_var_p (pb, j))
  1447. {
  1448. eqn sub = &(pb->eqs[e]);
  1449. int c = pb->eqs[e].coef[i];
  1450. int a = abs (c);
  1451. int e2;
  1452. if (dump_file && (dump_flags & TDF_DETAILS))
  1453. {
  1454. fprintf (dump_file,
  1455. "Found a single wild card equality: ");
  1456. omega_print_eq (dump_file, pb, &pb->eqs[e]);
  1457. fprintf (dump_file, "\n");
  1458. omega_print_problem (dump_file, pb);
  1459. }
  1460. for (e2 = pb->num_eqs - 1; e2 >= 0; e2--)
  1461. if (e != e2 && pb->eqs[e2].coef[i]
  1462. && (pb->eqs[e2].color == omega_red
  1463. || (pb->eqs[e2].color == omega_black
  1464. && pb->eqs[e].color == omega_black)))
  1465. {
  1466. eqn eqn = &(pb->eqs[e2]);
  1467. int var, k;
  1468. for (var = n_vars; var >= 0; var--)
  1469. eqn->coef[var] *= a;
  1470. k = eqn->coef[i];
  1471. for (var = n_vars; var >= 0; var--)
  1472. eqn->coef[var] -= sub->coef[var] * k / c;
  1473. eqn->coef[i] = 0;
  1474. divide_eqn_by_gcd (eqn, n_vars);
  1475. }
  1476. for (e2 = pb->num_geqs - 1; e2 >= 0; e2--)
  1477. if (pb->geqs[e2].coef[i]
  1478. && (pb->geqs[e2].color == omega_red
  1479. || (pb->eqs[e].color == omega_black
  1480. && pb->geqs[e2].color == omega_black)))
  1481. {
  1482. eqn eqn = &(pb->geqs[e2]);
  1483. int var, k;
  1484. for (var = n_vars; var >= 0; var--)
  1485. eqn->coef[var] *= a;
  1486. k = eqn->coef[i];
  1487. for (var = n_vars; var >= 0; var--)
  1488. eqn->coef[var] -= sub->coef[var] * k / c;
  1489. eqn->coef[i] = 0;
  1490. eqn->touched = 1;
  1491. renormalize = true;
  1492. }
  1493. for (e2 = pb->num_subs - 1; e2 >= 0; e2--)
  1494. if (pb->subs[e2].coef[i]
  1495. && (pb->subs[e2].color == omega_red
  1496. || (pb->subs[e2].color == omega_black
  1497. && pb->eqs[e].color == omega_black)))
  1498. {
  1499. eqn eqn = &(pb->subs[e2]);
  1500. int var, k;
  1501. for (var = n_vars; var >= 0; var--)
  1502. eqn->coef[var] *= a;
  1503. k = eqn->coef[i];
  1504. for (var = n_vars; var >= 0; var--)
  1505. eqn->coef[var] -= sub->coef[var] * k / c;
  1506. eqn->coef[i] = 0;
  1507. divide_eqn_by_gcd (eqn, n_vars);
  1508. }
  1509. if (dump_file && (dump_flags & TDF_DETAILS))
  1510. {
  1511. fprintf (dump_file, "cleaned-out wildcard: ");
  1512. omega_print_problem (dump_file, pb);
  1513. }
  1514. break;
  1515. }
  1516. }
  1517. if (renormalize)
  1518. normalize_omega_problem (pb);
  1519. }
  1520. /* Swap values contained in I and J. */
  1521. static inline void
  1522. swap (int *i, int *j)
  1523. {
  1524. int tmp;
  1525. tmp = *i;
  1526. *i = *j;
  1527. *j = tmp;
  1528. }
  1529. /* Swap values contained in I and J. */
  1530. static inline void
  1531. bswap (bool *i, bool *j)
  1532. {
  1533. bool tmp;
  1534. tmp = *i;
  1535. *i = *j;
  1536. *j = tmp;
  1537. }
  1538. /* Make variable IDX unprotected in PB, by swapping its index at the
  1539. PB->safe_vars rank. */
  1540. static inline void
  1541. omega_unprotect_1 (omega_pb pb, int *idx, bool *unprotect)
  1542. {
  1543. /* If IDX is protected... */
  1544. if (*idx < pb->safe_vars)
  1545. {
  1546. /* ... swap its index with the last non protected index. */
  1547. int j = pb->safe_vars;
  1548. int e;
  1549. for (e = pb->num_geqs - 1; e >= 0; e--)
  1550. {
  1551. pb->geqs[e].touched = 1;
  1552. swap (&pb->geqs[e].coef[*idx], &pb->geqs[e].coef[j]);
  1553. }
  1554. for (e = pb->num_eqs - 1; e >= 0; e--)
  1555. swap (&pb->eqs[e].coef[*idx], &pb->eqs[e].coef[j]);
  1556. for (e = pb->num_subs - 1; e >= 0; e--)
  1557. swap (&pb->subs[e].coef[*idx], &pb->subs[e].coef[j]);
  1558. if (unprotect)
  1559. bswap (&unprotect[*idx], &unprotect[j]);
  1560. swap (&pb->var[*idx], &pb->var[j]);
  1561. pb->forwarding_address[pb->var[*idx]] = *idx;
  1562. pb->forwarding_address[pb->var[j]] = j;
  1563. (*idx)--;
  1564. }
  1565. /* The variable at pb->safe_vars is also unprotected now. */
  1566. pb->safe_vars--;
  1567. }
  1568. /* During the Fourier-Motzkin elimination some variables are
  1569. substituted with other variables. This function resurrects the
  1570. substituted variables in PB. */
  1571. static void
  1572. resurrect_subs (omega_pb pb)
  1573. {
  1574. if (pb->num_subs > 0
  1575. && please_no_equalities_in_simplified_problems == 0)
  1576. {
  1577. int i, e, m;
  1578. if (dump_file && (dump_flags & TDF_DETAILS))
  1579. {
  1580. fprintf (dump_file,
  1581. "problem reduced, bringing variables back to life\n");
  1582. omega_print_problem (dump_file, pb);
  1583. }
  1584. for (i = 1; omega_safe_var_p (pb, i); i++)
  1585. if (omega_wildcard_p (pb, i))
  1586. omega_unprotect_1 (pb, &i, NULL);
  1587. m = pb->num_subs;
  1588. for (e = pb->num_geqs - 1; e >= 0; e--)
  1589. if (single_var_geq (&pb->geqs[e], pb->num_vars))
  1590. {
  1591. if (!omega_safe_var_p (pb, abs (pb->geqs[e].key)))
  1592. pb->geqs[e].key += (pb->geqs[e].key > 0 ? m : -m);
  1593. }
  1594. else
  1595. {
  1596. pb->geqs[e].touched = 1;
  1597. pb->geqs[e].key = 0;
  1598. }
  1599. for (i = pb->num_vars; !omega_safe_var_p (pb, i); i--)
  1600. {
  1601. pb->var[i + m] = pb->var[i];
  1602. for (e = pb->num_geqs - 1; e >= 0; e--)
  1603. pb->geqs[e].coef[i + m] = pb->geqs[e].coef[i];
  1604. for (e = pb->num_eqs - 1; e >= 0; e--)
  1605. pb->eqs[e].coef[i + m] = pb->eqs[e].coef[i];
  1606. for (e = pb->num_subs - 1; e >= 0; e--)
  1607. pb->subs[e].coef[i + m] = pb->subs[e].coef[i];
  1608. }
  1609. for (i = pb->safe_vars + m; !omega_safe_var_p (pb, i); i--)
  1610. {
  1611. for (e = pb->num_geqs - 1; e >= 0; e--)
  1612. pb->geqs[e].coef[i] = 0;
  1613. for (e = pb->num_eqs - 1; e >= 0; e--)
  1614. pb->eqs[e].coef[i] = 0;
  1615. for (e = pb->num_subs - 1; e >= 0; e--)
  1616. pb->subs[e].coef[i] = 0;
  1617. }
  1618. pb->num_vars += m;
  1619. for (e = pb->num_subs - 1; e >= 0; e--)
  1620. {
  1621. pb->var[pb->safe_vars + 1 + e] = pb->subs[e].key;
  1622. omega_copy_eqn (&(pb->eqs[pb->num_eqs]), &(pb->subs[e]),
  1623. pb->num_vars);
  1624. pb->eqs[pb->num_eqs].coef[pb->safe_vars + 1 + e] = -1;
  1625. pb->eqs[pb->num_eqs].color = omega_black;
  1626. if (dump_file && (dump_flags & TDF_DETAILS))
  1627. {
  1628. fprintf (dump_file, "brought back: ");
  1629. omega_print_eq (dump_file, pb, &pb->eqs[pb->num_eqs]);
  1630. fprintf (dump_file, "\n");
  1631. }
  1632. pb->num_eqs++;
  1633. gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
  1634. }
  1635. pb->safe_vars += m;
  1636. pb->num_subs = 0;
  1637. if (dump_file && (dump_flags & TDF_DETAILS))
  1638. {
  1639. fprintf (dump_file, "variables brought back to life\n");
  1640. omega_print_problem (dump_file, pb);
  1641. }
  1642. cleanout_wildcards (pb);
  1643. }
  1644. }
  1645. static inline bool
  1646. implies (unsigned int a, unsigned int b)
  1647. {
  1648. return (a == (a & b));
  1649. }
  1650. /* Eliminate redundant equations in PB. When EXPENSIVE is true, an
  1651. extra step is performed. Returns omega_false when there exist no
  1652. solution, omega_true otherwise. */
  1653. enum omega_result
  1654. omega_eliminate_redundant (omega_pb pb, bool expensive)
  1655. {
  1656. int c, e, e1, e2, e3, p, q, i, k, alpha, alpha1, alpha2, alpha3;
  1657. bool *is_dead = XNEWVEC (bool, OMEGA_MAX_GEQS);
  1658. omega_pb tmp_problem;
  1659. /* {P,Z,N}EQS = {Positive,Zero,Negative} Equations. */
  1660. unsigned int *peqs = XNEWVEC (unsigned int, OMEGA_MAX_GEQS);
  1661. unsigned int *zeqs = XNEWVEC (unsigned int, OMEGA_MAX_GEQS);
  1662. unsigned int *neqs = XNEWVEC (unsigned int, OMEGA_MAX_GEQS);
  1663. /* PP = Possible Positives, PZ = Possible Zeros, PN = Possible Negatives */
  1664. unsigned int pp, pz, pn;
  1665. if (dump_file && (dump_flags & TDF_DETAILS))
  1666. {
  1667. fprintf (dump_file, "in eliminate Redundant:\n");
  1668. omega_print_problem (dump_file, pb);
  1669. }
  1670. for (e = pb->num_geqs - 1; e >= 0; e--)
  1671. {
  1672. int tmp = 1;
  1673. is_dead[e] = false;
  1674. peqs[e] = zeqs[e] = neqs[e] = 0;
  1675. for (i = pb->num_vars; i >= 1; i--)
  1676. {
  1677. if (pb->geqs[e].coef[i] > 0)
  1678. peqs[e] |= tmp;
  1679. else if (pb->geqs[e].coef[i] < 0)
  1680. neqs[e] |= tmp;
  1681. else
  1682. zeqs[e] |= tmp;
  1683. tmp <<= 1;
  1684. }
  1685. }
  1686. for (e1 = pb->num_geqs - 1; e1 >= 0; e1--)
  1687. if (!is_dead[e1])
  1688. for (e2 = e1 - 1; e2 >= 0; e2--)
  1689. if (!is_dead[e2])
  1690. {
  1691. for (p = pb->num_vars; p > 1; p--)
  1692. for (q = p - 1; q > 0; q--)
  1693. if ((alpha = pb->geqs[e1].coef[p] * pb->geqs[e2].coef[q]
  1694. - pb->geqs[e2].coef[p] * pb->geqs[e1].coef[q]) != 0)
  1695. goto foundPQ;
  1696. continue;
  1697. foundPQ:
  1698. pz = ((zeqs[e1] & zeqs[e2]) | (peqs[e1] & neqs[e2])
  1699. | (neqs[e1] & peqs[e2]));
  1700. pp = peqs[e1] | peqs[e2];
  1701. pn = neqs[e1] | neqs[e2];
  1702. for (e3 = pb->num_geqs - 1; e3 >= 0; e3--)
  1703. if (e3 != e1 && e3 != e2)
  1704. {
  1705. if (!implies (zeqs[e3], pz))
  1706. goto nextE3;
  1707. alpha1 = (pb->geqs[e2].coef[q] * pb->geqs[e3].coef[p]
  1708. - pb->geqs[e2].coef[p] * pb->geqs[e3].coef[q]);
  1709. alpha2 = -(pb->geqs[e1].coef[q] * pb->geqs[e3].coef[p]
  1710. - pb->geqs[e1].coef[p] * pb->geqs[e3].coef[q]);
  1711. alpha3 = alpha;
  1712. if (alpha1 * alpha2 <= 0)
  1713. goto nextE3;
  1714. if (alpha1 < 0)
  1715. {
  1716. alpha1 = -alpha1;
  1717. alpha2 = -alpha2;
  1718. alpha3 = -alpha3;
  1719. }
  1720. if (alpha3 > 0)
  1721. {
  1722. /* Trying to prove e3 is redundant. */
  1723. if (!implies (peqs[e3], pp)
  1724. || !implies (neqs[e3], pn))
  1725. goto nextE3;
  1726. if (pb->geqs[e3].color == omega_black
  1727. && (pb->geqs[e1].color == omega_red
  1728. || pb->geqs[e2].color == omega_red))
  1729. goto nextE3;
  1730. for (k = pb->num_vars; k >= 1; k--)
  1731. if (alpha3 * pb->geqs[e3].coef[k]
  1732. != (alpha1 * pb->geqs[e1].coef[k]
  1733. + alpha2 * pb->geqs[e2].coef[k]))
  1734. goto nextE3;
  1735. c = (alpha1 * pb->geqs[e1].coef[0]
  1736. + alpha2 * pb->geqs[e2].coef[0]);
  1737. if (c < alpha3 * (pb->geqs[e3].coef[0] + 1))
  1738. {
  1739. if (dump_file && (dump_flags & TDF_DETAILS))
  1740. {
  1741. fprintf (dump_file,
  1742. "found redundant inequality\n");
  1743. fprintf (dump_file,
  1744. "alpha1, alpha2, alpha3 = %d,%d,%d\n",
  1745. alpha1, alpha2, alpha3);
  1746. omega_print_geq (dump_file, pb, &(pb->geqs[e1]));
  1747. fprintf (dump_file, "\n");
  1748. omega_print_geq (dump_file, pb, &(pb->geqs[e2]));
  1749. fprintf (dump_file, "\n=> ");
  1750. omega_print_geq (dump_file, pb, &(pb->geqs[e3]));
  1751. fprintf (dump_file, "\n\n");
  1752. }
  1753. is_dead[e3] = true;
  1754. }
  1755. }
  1756. else
  1757. {
  1758. /* Trying to prove e3 <= 0 and therefore e3 = 0,
  1759. or trying to prove e3 < 0, and therefore the
  1760. problem has no solutions. */
  1761. if (!implies (peqs[e3], pn)
  1762. || !implies (neqs[e3], pp))
  1763. goto nextE3;
  1764. if (pb->geqs[e1].color == omega_red
  1765. || pb->geqs[e2].color == omega_red
  1766. || pb->geqs[e3].color == omega_red)
  1767. goto nextE3;
  1768. /* verify alpha1*v1+alpha2*v2 = alpha3*v3 */
  1769. for (k = pb->num_vars; k >= 1; k--)
  1770. if (alpha3 * pb->geqs[e3].coef[k]
  1771. != (alpha1 * pb->geqs[e1].coef[k]
  1772. + alpha2 * pb->geqs[e2].coef[k]))
  1773. goto nextE3;
  1774. c = (alpha1 * pb->geqs[e1].coef[0]
  1775. + alpha2 * pb->geqs[e2].coef[0]);
  1776. if (c < alpha3 * (pb->geqs[e3].coef[0]))
  1777. {
  1778. /* We just proved e3 < 0, so no solutions exist. */
  1779. if (dump_file && (dump_flags & TDF_DETAILS))
  1780. {
  1781. fprintf (dump_file,
  1782. "found implied over tight inequality\n");
  1783. fprintf (dump_file,
  1784. "alpha1, alpha2, alpha3 = %d,%d,%d\n",
  1785. alpha1, alpha2, -alpha3);
  1786. omega_print_geq (dump_file, pb, &(pb->geqs[e1]));
  1787. fprintf (dump_file, "\n");
  1788. omega_print_geq (dump_file, pb, &(pb->geqs[e2]));
  1789. fprintf (dump_file, "\n=> not ");
  1790. omega_print_geq (dump_file, pb, &(pb->geqs[e3]));
  1791. fprintf (dump_file, "\n\n");
  1792. }
  1793. free (is_dead);
  1794. free (peqs);
  1795. free (zeqs);
  1796. free (neqs);
  1797. return omega_false;
  1798. }
  1799. else if (c < alpha3 * (pb->geqs[e3].coef[0] - 1))
  1800. {
  1801. /* We just proved that e3 <=0, so e3 = 0. */
  1802. if (dump_file && (dump_flags & TDF_DETAILS))
  1803. {
  1804. fprintf (dump_file,
  1805. "found implied tight inequality\n");
  1806. fprintf (dump_file,
  1807. "alpha1, alpha2, alpha3 = %d,%d,%d\n",
  1808. alpha1, alpha2, -alpha3);
  1809. omega_print_geq (dump_file, pb, &(pb->geqs[e1]));
  1810. fprintf (dump_file, "\n");
  1811. omega_print_geq (dump_file, pb, &(pb->geqs[e2]));
  1812. fprintf (dump_file, "\n=> inverse ");
  1813. omega_print_geq (dump_file, pb, &(pb->geqs[e3]));
  1814. fprintf (dump_file, "\n\n");
  1815. }
  1816. omega_copy_eqn (&pb->eqs[pb->num_eqs++],
  1817. &pb->geqs[e3], pb->num_vars);
  1818. gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
  1819. adding_equality_constraint (pb, pb->num_eqs - 1);
  1820. is_dead[e3] = true;
  1821. }
  1822. }
  1823. nextE3:;
  1824. }
  1825. }
  1826. /* Delete the inequalities that were marked as dead. */
  1827. for (e = pb->num_geqs - 1; e >= 0; e--)
  1828. if (is_dead[e])
  1829. omega_delete_geq (pb, e, pb->num_vars);
  1830. if (!expensive)
  1831. goto eliminate_redundant_done;
  1832. tmp_problem = XNEW (struct omega_pb_d);
  1833. conservative++;
  1834. for (e = pb->num_geqs - 1; e >= 0; e--)
  1835. {
  1836. if (dump_file && (dump_flags & TDF_DETAILS))
  1837. {
  1838. fprintf (dump_file,
  1839. "checking equation %d to see if it is redundant: ", e);
  1840. omega_print_geq (dump_file, pb, &(pb->geqs[e]));
  1841. fprintf (dump_file, "\n");
  1842. }
  1843. omega_copy_problem (tmp_problem, pb);
  1844. omega_negate_geq (tmp_problem, e);
  1845. tmp_problem->safe_vars = 0;
  1846. tmp_problem->variables_freed = false;
  1847. if (omega_solve_problem (tmp_problem, omega_false) == omega_false)
  1848. omega_delete_geq (pb, e, pb->num_vars);
  1849. }
  1850. free (tmp_problem);
  1851. conservative--;
  1852. if (!omega_reduce_with_subs)
  1853. {
  1854. resurrect_subs (pb);
  1855. gcc_assert (please_no_equalities_in_simplified_problems
  1856. || pb->num_subs == 0);
  1857. }
  1858. eliminate_redundant_done:
  1859. free (is_dead);
  1860. free (peqs);
  1861. free (zeqs);
  1862. free (neqs);
  1863. return omega_true;
  1864. }
  1865. /* For each inequality that has coefficients bigger than 20, try to
  1866. create a new constraint that cannot be derived from the original
  1867. constraint and that has smaller coefficients. Add the new
  1868. constraint at the end of geqs. Return the number of inequalities
  1869. that have been added to PB. */
  1870. static int
  1871. smooth_weird_equations (omega_pb pb)
  1872. {
  1873. int e1, e2, e3, p, q, k, alpha, alpha1, alpha2, alpha3;
  1874. int c;
  1875. int v;
  1876. int result = 0;
  1877. for (e1 = pb->num_geqs - 1; e1 >= 0; e1--)
  1878. if (pb->geqs[e1].color == omega_black)
  1879. {
  1880. int g = 999999;
  1881. for (v = pb->num_vars; v >= 1; v--)
  1882. if (pb->geqs[e1].coef[v] != 0 && abs (pb->geqs[e1].coef[v]) < g)
  1883. g = abs (pb->geqs[e1].coef[v]);
  1884. /* Magic number. */
  1885. if (g > 20)
  1886. {
  1887. e3 = pb->num_geqs;
  1888. for (v = pb->num_vars; v >= 1; v--)
  1889. pb->geqs[e3].coef[v] = int_div (6 * pb->geqs[e1].coef[v] + g / 2,
  1890. g);
  1891. pb->geqs[e3].color = omega_black;
  1892. pb->geqs[e3].touched = 1;
  1893. /* Magic number. */
  1894. pb->geqs[e3].coef[0] = 9997;
  1895. if (dump_file && (dump_flags & TDF_DETAILS))
  1896. {
  1897. fprintf (dump_file, "Checking to see if we can derive: ");
  1898. omega_print_geq (dump_file, pb, &pb->geqs[e3]);
  1899. fprintf (dump_file, "\n from: ");
  1900. omega_print_geq (dump_file, pb, &pb->geqs[e1]);
  1901. fprintf (dump_file, "\n");
  1902. }
  1903. for (e2 = pb->num_geqs - 1; e2 >= 0; e2--)
  1904. if (e1 != e2 && pb->geqs[e2].color == omega_black)
  1905. {
  1906. for (p = pb->num_vars; p > 1; p--)
  1907. {
  1908. for (q = p - 1; q > 0; q--)
  1909. {
  1910. alpha =
  1911. (pb->geqs[e1].coef[p] * pb->geqs[e2].coef[q] -
  1912. pb->geqs[e2].coef[p] * pb->geqs[e1].coef[q]);
  1913. if (alpha != 0)
  1914. goto foundPQ;
  1915. }
  1916. }
  1917. continue;
  1918. foundPQ:
  1919. alpha1 = (pb->geqs[e2].coef[q] * pb->geqs[e3].coef[p]
  1920. - pb->geqs[e2].coef[p] * pb->geqs[e3].coef[q]);
  1921. alpha2 = -(pb->geqs[e1].coef[q] * pb->geqs[e3].coef[p]
  1922. - pb->geqs[e1].coef[p] * pb->geqs[e3].coef[q]);
  1923. alpha3 = alpha;
  1924. if (alpha1 * alpha2 <= 0)
  1925. continue;
  1926. if (alpha1 < 0)
  1927. {
  1928. alpha1 = -alpha1;
  1929. alpha2 = -alpha2;
  1930. alpha3 = -alpha3;
  1931. }
  1932. if (alpha3 > 0)
  1933. {
  1934. /* Try to prove e3 is redundant: verify
  1935. alpha1*v1 + alpha2*v2 = alpha3*v3. */
  1936. for (k = pb->num_vars; k >= 1; k--)
  1937. if (alpha3 * pb->geqs[e3].coef[k]
  1938. != (alpha1 * pb->geqs[e1].coef[k]
  1939. + alpha2 * pb->geqs[e2].coef[k]))
  1940. goto nextE2;
  1941. c = alpha1 * pb->geqs[e1].coef[0]
  1942. + alpha2 * pb->geqs[e2].coef[0];
  1943. if (c < alpha3 * (pb->geqs[e3].coef[0] + 1))
  1944. pb->geqs[e3].coef[0] = int_div (c, alpha3);
  1945. }
  1946. nextE2:;
  1947. }
  1948. if (pb->geqs[e3].coef[0] < 9997)
  1949. {
  1950. result++;
  1951. pb->num_geqs++;
  1952. if (dump_file && (dump_flags & TDF_DETAILS))
  1953. {
  1954. fprintf (dump_file,
  1955. "Smoothing weird equations; adding:\n");
  1956. omega_print_geq (dump_file, pb, &pb->geqs[e3]);
  1957. fprintf (dump_file, "\nto:\n");
  1958. omega_print_problem (dump_file, pb);
  1959. fprintf (dump_file, "\n\n");
  1960. }
  1961. }
  1962. }
  1963. }
  1964. return result;
  1965. }
  1966. /* Replace tuples of inequalities, that define upper and lower half
  1967. spaces, with an equation. */
  1968. static void
  1969. coalesce (omega_pb pb)
  1970. {
  1971. int e, e2;
  1972. int colors = 0;
  1973. bool *is_dead;
  1974. int found_something = 0;
  1975. for (e = 0; e < pb->num_geqs; e++)
  1976. if (pb->geqs[e].color == omega_red)
  1977. colors++;
  1978. if (colors < 2)
  1979. return;
  1980. is_dead = XNEWVEC (bool, OMEGA_MAX_GEQS);
  1981. for (e = 0; e < pb->num_geqs; e++)
  1982. is_dead[e] = false;
  1983. for (e = 0; e < pb->num_geqs; e++)
  1984. if (pb->geqs[e].color == omega_red
  1985. && !pb->geqs[e].touched)
  1986. for (e2 = e + 1; e2 < pb->num_geqs; e2++)
  1987. if (!pb->geqs[e2].touched
  1988. && pb->geqs[e].key == -pb->geqs[e2].key
  1989. && pb->geqs[e].coef[0] == -pb->geqs[e2].coef[0]
  1990. && pb->geqs[e2].color == omega_red)
  1991. {
  1992. omega_copy_eqn (&pb->eqs[pb->num_eqs++], &pb->geqs[e],
  1993. pb->num_vars);
  1994. gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
  1995. found_something++;
  1996. is_dead[e] = true;
  1997. is_dead[e2] = true;
  1998. }
  1999. for (e = pb->num_geqs - 1; e >= 0; e--)
  2000. if (is_dead[e])
  2001. omega_delete_geq (pb, e, pb->num_vars);
  2002. if (dump_file && (dump_flags & TDF_DETAILS) && found_something)
  2003. {
  2004. fprintf (dump_file, "Coalesced pb->geqs into %d EQ's:\n",
  2005. found_something);
  2006. omega_print_problem (dump_file, pb);
  2007. }
  2008. free (is_dead);
  2009. }
  2010. /* Eliminate red inequalities from PB. When ELIMINATE_ALL is
  2011. true, continue to eliminate all the red inequalities. */
  2012. void
  2013. omega_eliminate_red (omega_pb pb, bool eliminate_all)
  2014. {
  2015. int e, e2, e3, i, j, k, a, alpha1, alpha2;
  2016. int c = 0;
  2017. bool *is_dead = XNEWVEC (bool, OMEGA_MAX_GEQS);
  2018. int dead_count = 0;
  2019. int red_found;
  2020. omega_pb tmp_problem;
  2021. if (dump_file && (dump_flags & TDF_DETAILS))
  2022. {
  2023. fprintf (dump_file, "in eliminate RED:\n");
  2024. omega_print_problem (dump_file, pb);
  2025. }
  2026. if (pb->num_eqs > 0)
  2027. omega_simplify_problem (pb);
  2028. for (e = pb->num_geqs - 1; e >= 0; e--)
  2029. is_dead[e] = false;
  2030. for (e = pb->num_geqs - 1; e >= 0; e--)
  2031. if (pb->geqs[e].color == omega_black && !is_dead[e])
  2032. for (e2 = e - 1; e2 >= 0; e2--)
  2033. if (pb->geqs[e2].color == omega_black
  2034. && !is_dead[e2])
  2035. {
  2036. a = 0;
  2037. for (i = pb->num_vars; i > 1; i--)
  2038. for (j = i - 1; j > 0; j--)
  2039. if ((a = (pb->geqs[e].coef[i] * pb->geqs[e2].coef[j]
  2040. - pb->geqs[e2].coef[i] * pb->geqs[e].coef[j])) != 0)
  2041. goto found_pair;
  2042. continue;
  2043. found_pair:
  2044. if (dump_file && (dump_flags & TDF_DETAILS))
  2045. {
  2046. fprintf (dump_file,
  2047. "found two equations to combine, i = %s, ",
  2048. omega_variable_to_str (pb, i));
  2049. fprintf (dump_file, "j = %s, alpha = %d\n",
  2050. omega_variable_to_str (pb, j), a);
  2051. omega_print_geq (dump_file, pb, &(pb->geqs[e]));
  2052. fprintf (dump_file, "\n");
  2053. omega_print_geq (dump_file, pb, &(pb->geqs[e2]));
  2054. fprintf (dump_file, "\n");
  2055. }
  2056. for (e3 = pb->num_geqs - 1; e3 >= 0; e3--)
  2057. if (pb->geqs[e3].color == omega_red)
  2058. {
  2059. alpha1 = (pb->geqs[e2].coef[j] * pb->geqs[e3].coef[i]
  2060. - pb->geqs[e2].coef[i] * pb->geqs[e3].coef[j]);
  2061. alpha2 = -(pb->geqs[e].coef[j] * pb->geqs[e3].coef[i]
  2062. - pb->geqs[e].coef[i] * pb->geqs[e3].coef[j]);
  2063. if ((a > 0 && alpha1 > 0 && alpha2 > 0)
  2064. || (a < 0 && alpha1 < 0 && alpha2 < 0))
  2065. {
  2066. if (dump_file && (dump_flags & TDF_DETAILS))
  2067. {
  2068. fprintf (dump_file,
  2069. "alpha1 = %d, alpha2 = %d;"
  2070. "comparing against: ",
  2071. alpha1, alpha2);
  2072. omega_print_geq (dump_file, pb, &(pb->geqs[e3]));
  2073. fprintf (dump_file, "\n");
  2074. }
  2075. for (k = pb->num_vars; k >= 0; k--)
  2076. {
  2077. c = (alpha1 * pb->geqs[e].coef[k]
  2078. + alpha2 * pb->geqs[e2].coef[k]);
  2079. if (c != a * pb->geqs[e3].coef[k])
  2080. break;
  2081. if (dump_file && (dump_flags & TDF_DETAILS) && k > 0)
  2082. fprintf (dump_file, " %s: %d, %d\n",
  2083. omega_variable_to_str (pb, k), c,
  2084. a * pb->geqs[e3].coef[k]);
  2085. }
  2086. if (k < 0
  2087. || (k == 0 &&
  2088. ((a > 0 && c < a * pb->geqs[e3].coef[k])
  2089. || (a < 0 && c > a * pb->geqs[e3].coef[k]))))
  2090. {
  2091. if (dump_file && (dump_flags & TDF_DETAILS))
  2092. {
  2093. dead_count++;
  2094. fprintf (dump_file,
  2095. "red equation#%d is dead "
  2096. "(%d dead so far, %d remain)\n",
  2097. e3, dead_count,
  2098. pb->num_geqs - dead_count);
  2099. omega_print_geq (dump_file, pb, &(pb->geqs[e]));
  2100. fprintf (dump_file, "\n");
  2101. omega_print_geq (dump_file, pb, &(pb->geqs[e2]));
  2102. fprintf (dump_file, "\n");
  2103. omega_print_geq (dump_file, pb, &(pb->geqs[e3]));
  2104. fprintf (dump_file, "\n");
  2105. }
  2106. is_dead[e3] = true;
  2107. }
  2108. }
  2109. }
  2110. }
  2111. for (e = pb->num_geqs - 1; e >= 0; e--)
  2112. if (is_dead[e])
  2113. omega_delete_geq (pb, e, pb->num_vars);
  2114. free (is_dead);
  2115. if (dump_file && (dump_flags & TDF_DETAILS))
  2116. {
  2117. fprintf (dump_file, "in eliminate RED, easy tests done:\n");
  2118. omega_print_problem (dump_file, pb);
  2119. }
  2120. for (red_found = 0, e = pb->num_geqs - 1; e >= 0; e--)
  2121. if (pb->geqs[e].color == omega_red)
  2122. {
  2123. red_found = 1;
  2124. break;
  2125. }
  2126. if (!red_found)
  2127. {
  2128. if (dump_file && (dump_flags & TDF_DETAILS))
  2129. fprintf (dump_file, "fast checks worked\n");
  2130. if (!omega_reduce_with_subs)
  2131. gcc_assert (please_no_equalities_in_simplified_problems
  2132. || pb->num_subs == 0);
  2133. return;
  2134. }
  2135. if (!omega_verify_simplification
  2136. && verify_omega_pb (pb) == omega_false)
  2137. return;
  2138. conservative++;
  2139. tmp_problem = XNEW (struct omega_pb_d);
  2140. for (e = pb->num_geqs - 1; e >= 0; e--)
  2141. if (pb->geqs[e].color == omega_red)
  2142. {
  2143. if (dump_file && (dump_flags & TDF_DETAILS))
  2144. {
  2145. fprintf (dump_file,
  2146. "checking equation %d to see if it is redundant: ", e);
  2147. omega_print_geq (dump_file, pb, &(pb->geqs[e]));
  2148. fprintf (dump_file, "\n");
  2149. }
  2150. omega_copy_problem (tmp_problem, pb);
  2151. omega_negate_geq (tmp_problem, e);
  2152. tmp_problem->safe_vars = 0;
  2153. tmp_problem->variables_freed = false;
  2154. tmp_problem->num_subs = 0;
  2155. if (omega_solve_problem (tmp_problem, omega_false) == omega_false)
  2156. {
  2157. if (dump_file && (dump_flags & TDF_DETAILS))
  2158. fprintf (dump_file, "it is redundant\n");
  2159. omega_delete_geq (pb, e, pb->num_vars);
  2160. }
  2161. else
  2162. {
  2163. if (dump_file && (dump_flags & TDF_DETAILS))
  2164. fprintf (dump_file, "it is not redundant\n");
  2165. if (!eliminate_all)
  2166. {
  2167. if (dump_file && (dump_flags & TDF_DETAILS))
  2168. fprintf (dump_file, "no need to check other red equations\n");
  2169. break;
  2170. }
  2171. }
  2172. }
  2173. conservative--;
  2174. free (tmp_problem);
  2175. /* omega_simplify_problem (pb); */
  2176. if (!omega_reduce_with_subs)
  2177. gcc_assert (please_no_equalities_in_simplified_problems
  2178. || pb->num_subs == 0);
  2179. }
  2180. /* Transform some wildcard variables to non-safe variables. */
  2181. static void
  2182. chain_unprotect (omega_pb pb)
  2183. {
  2184. int i, e;
  2185. bool *unprotect = XNEWVEC (bool, OMEGA_MAX_VARS);
  2186. for (i = 1; omega_safe_var_p (pb, i); i++)
  2187. {
  2188. unprotect[i] = omega_wildcard_p (pb, i);
  2189. for (e = pb->num_subs - 1; e >= 0; e--)
  2190. if (pb->subs[e].coef[i])
  2191. unprotect[i] = false;
  2192. }
  2193. if (dump_file && (dump_flags & TDF_DETAILS))
  2194. {
  2195. fprintf (dump_file, "Doing chain reaction unprotection\n");
  2196. omega_print_problem (dump_file, pb);
  2197. for (i = 1; omega_safe_var_p (pb, i); i++)
  2198. if (unprotect[i])
  2199. fprintf (dump_file, "unprotecting %s\n",
  2200. omega_variable_to_str (pb, i));
  2201. }
  2202. for (i = 1; omega_safe_var_p (pb, i); i++)
  2203. if (unprotect[i])
  2204. omega_unprotect_1 (pb, &i, unprotect);
  2205. if (dump_file && (dump_flags & TDF_DETAILS))
  2206. {
  2207. fprintf (dump_file, "After chain reactions\n");
  2208. omega_print_problem (dump_file, pb);
  2209. }
  2210. free (unprotect);
  2211. }
  2212. /* Reduce problem PB. */
  2213. static void
  2214. omega_problem_reduced (omega_pb pb)
  2215. {
  2216. if (omega_verify_simplification
  2217. && !in_approximate_mode
  2218. && verify_omega_pb (pb) == omega_false)
  2219. return;
  2220. if (PARAM_VALUE (PARAM_OMEGA_ELIMINATE_REDUNDANT_CONSTRAINTS)
  2221. && !omega_eliminate_redundant (pb, true))
  2222. return;
  2223. omega_found_reduction = omega_true;
  2224. if (!please_no_equalities_in_simplified_problems)
  2225. coalesce (pb);
  2226. if (omega_reduce_with_subs
  2227. || please_no_equalities_in_simplified_problems)
  2228. chain_unprotect (pb);
  2229. else
  2230. resurrect_subs (pb);
  2231. if (!return_single_result)
  2232. {
  2233. int i;
  2234. for (i = 1; omega_safe_var_p (pb, i); i++)
  2235. pb->forwarding_address[pb->var[i]] = i;
  2236. for (i = 0; i < pb->num_subs; i++)
  2237. pb->forwarding_address[pb->subs[i].key] = -i - 1;
  2238. (*omega_when_reduced) (pb);
  2239. }
  2240. if (dump_file && (dump_flags & TDF_DETAILS))
  2241. {
  2242. fprintf (dump_file, "-------------------------------------------\n");
  2243. fprintf (dump_file, "problem reduced:\n");
  2244. omega_print_problem (dump_file, pb);
  2245. fprintf (dump_file, "-------------------------------------------\n");
  2246. }
  2247. }
  2248. /* Eliminates all the free variables for problem PB, that is all the
  2249. variables from FV to PB->NUM_VARS. */
  2250. static void
  2251. omega_free_eliminations (omega_pb pb, int fv)
  2252. {
  2253. bool try_again = true;
  2254. int i, e, e2;
  2255. int n_vars = pb->num_vars;
  2256. while (try_again)
  2257. {
  2258. try_again = false;
  2259. for (i = n_vars; i > fv; i--)
  2260. {
  2261. for (e = pb->num_geqs - 1; e >= 0; e--)
  2262. if (pb->geqs[e].coef[i])
  2263. break;
  2264. if (e < 0)
  2265. e2 = e;
  2266. else if (pb->geqs[e].coef[i] > 0)
  2267. {
  2268. for (e2 = e - 1; e2 >= 0; e2--)
  2269. if (pb->geqs[e2].coef[i] < 0)
  2270. break;
  2271. }
  2272. else
  2273. {
  2274. for (e2 = e - 1; e2 >= 0; e2--)
  2275. if (pb->geqs[e2].coef[i] > 0)
  2276. break;
  2277. }
  2278. if (e2 < 0)
  2279. {
  2280. int e3;
  2281. for (e3 = pb->num_subs - 1; e3 >= 0; e3--)
  2282. if (pb->subs[e3].coef[i])
  2283. break;
  2284. if (e3 >= 0)
  2285. continue;
  2286. for (e3 = pb->num_eqs - 1; e3 >= 0; e3--)
  2287. if (pb->eqs[e3].coef[i])
  2288. break;
  2289. if (e3 >= 0)
  2290. continue;
  2291. if (dump_file && (dump_flags & TDF_DETAILS))
  2292. fprintf (dump_file, "a free elimination of %s\n",
  2293. omega_variable_to_str (pb, i));
  2294. if (e >= 0)
  2295. {
  2296. omega_delete_geq (pb, e, n_vars);
  2297. for (e--; e >= 0; e--)
  2298. if (pb->geqs[e].coef[i])
  2299. omega_delete_geq (pb, e, n_vars);
  2300. try_again = (i < n_vars);
  2301. }
  2302. omega_delete_variable (pb, i);
  2303. n_vars = pb->num_vars;
  2304. }
  2305. }
  2306. }
  2307. if (dump_file && (dump_flags & TDF_DETAILS))
  2308. {
  2309. fprintf (dump_file, "\nafter free eliminations:\n");
  2310. omega_print_problem (dump_file, pb);
  2311. fprintf (dump_file, "\n");
  2312. }
  2313. }
  2314. /* Do free red eliminations. */
  2315. static void
  2316. free_red_eliminations (omega_pb pb)
  2317. {
  2318. bool try_again = true;
  2319. int i, e, e2;
  2320. int n_vars = pb->num_vars;
  2321. bool *is_red_var = XNEWVEC (bool, OMEGA_MAX_VARS);
  2322. bool *is_dead_var = XNEWVEC (bool, OMEGA_MAX_VARS);
  2323. bool *is_dead_geq = XNEWVEC (bool, OMEGA_MAX_GEQS);
  2324. for (i = n_vars; i > 0; i--)
  2325. {
  2326. is_red_var[i] = false;
  2327. is_dead_var[i] = false;
  2328. }
  2329. for (e = pb->num_geqs - 1; e >= 0; e--)
  2330. {
  2331. is_dead_geq[e] = false;
  2332. if (pb->geqs[e].color == omega_red)
  2333. for (i = n_vars; i > 0; i--)
  2334. if (pb->geqs[e].coef[i] != 0)
  2335. is_red_var[i] = true;
  2336. }
  2337. while (try_again)
  2338. {
  2339. try_again = false;
  2340. for (i = n_vars; i > 0; i--)
  2341. if (!is_red_var[i] && !is_dead_var[i])
  2342. {
  2343. for (e = pb->num_geqs - 1; e >= 0; e--)
  2344. if (!is_dead_geq[e] && pb->geqs[e].coef[i])
  2345. break;
  2346. if (e < 0)
  2347. e2 = e;
  2348. else if (pb->geqs[e].coef[i] > 0)
  2349. {
  2350. for (e2 = e - 1; e2 >= 0; e2--)
  2351. if (!is_dead_geq[e2] && pb->geqs[e2].coef[i] < 0)
  2352. break;
  2353. }
  2354. else
  2355. {
  2356. for (e2 = e - 1; e2 >= 0; e2--)
  2357. if (!is_dead_geq[e2] && pb->geqs[e2].coef[i] > 0)
  2358. break;
  2359. }
  2360. if (e2 < 0)
  2361. {
  2362. int e3;
  2363. for (e3 = pb->num_subs - 1; e3 >= 0; e3--)
  2364. if (pb->subs[e3].coef[i])
  2365. break;
  2366. if (e3 >= 0)
  2367. continue;
  2368. for (e3 = pb->num_eqs - 1; e3 >= 0; e3--)
  2369. if (pb->eqs[e3].coef[i])
  2370. break;
  2371. if (e3 >= 0)
  2372. continue;
  2373. if (dump_file && (dump_flags & TDF_DETAILS))
  2374. fprintf (dump_file, "a free red elimination of %s\n",
  2375. omega_variable_to_str (pb, i));
  2376. for (; e >= 0; e--)
  2377. if (pb->geqs[e].coef[i])
  2378. is_dead_geq[e] = true;
  2379. try_again = true;
  2380. is_dead_var[i] = true;
  2381. }
  2382. }
  2383. }
  2384. for (e = pb->num_geqs - 1; e >= 0; e--)
  2385. if (is_dead_geq[e])
  2386. omega_delete_geq (pb, e, n_vars);
  2387. for (i = n_vars; i > 0; i--)
  2388. if (is_dead_var[i])
  2389. omega_delete_variable (pb, i);
  2390. if (dump_file && (dump_flags & TDF_DETAILS))
  2391. {
  2392. fprintf (dump_file, "\nafter free red eliminations:\n");
  2393. omega_print_problem (dump_file, pb);
  2394. fprintf (dump_file, "\n");
  2395. }
  2396. free (is_red_var);
  2397. free (is_dead_var);
  2398. free (is_dead_geq);
  2399. }
  2400. /* For equation EQ of the form "0 = EQN", insert in PB two
  2401. inequalities "0 <= EQN" and "0 <= -EQN". */
  2402. void
  2403. omega_convert_eq_to_geqs (omega_pb pb, int eq)
  2404. {
  2405. int i;
  2406. if (dump_file && (dump_flags & TDF_DETAILS))
  2407. fprintf (dump_file, "Converting Eq to Geqs\n");
  2408. /* Insert "0 <= EQN". */
  2409. omega_copy_eqn (&pb->geqs[pb->num_geqs], &pb->eqs[eq], pb->num_vars);
  2410. pb->geqs[pb->num_geqs].touched = 1;
  2411. pb->num_geqs++;
  2412. /* Insert "0 <= -EQN". */
  2413. omega_copy_eqn (&pb->geqs[pb->num_geqs], &pb->eqs[eq], pb->num_vars);
  2414. pb->geqs[pb->num_geqs].touched = 1;
  2415. for (i = 0; i <= pb->num_vars; i++)
  2416. pb->geqs[pb->num_geqs].coef[i] *= -1;
  2417. pb->num_geqs++;
  2418. if (dump_file && (dump_flags & TDF_DETAILS))
  2419. omega_print_problem (dump_file, pb);
  2420. }
  2421. /* Eliminates variable I from PB. */
  2422. static void
  2423. omega_do_elimination (omega_pb pb, int e, int i)
  2424. {
  2425. eqn sub = omega_alloc_eqns (0, 1);
  2426. int c;
  2427. int n_vars = pb->num_vars;
  2428. if (dump_file && (dump_flags & TDF_DETAILS))
  2429. fprintf (dump_file, "eliminating variable %s\n",
  2430. omega_variable_to_str (pb, i));
  2431. omega_copy_eqn (sub, &pb->eqs[e], pb->num_vars);
  2432. c = sub->coef[i];
  2433. sub->coef[i] = 0;
  2434. if (c == 1 || c == -1)
  2435. {
  2436. if (pb->eqs[e].color == omega_red)
  2437. {
  2438. bool fB;
  2439. omega_substitute_red (pb, sub, i, c, &fB);
  2440. if (fB)
  2441. omega_convert_eq_to_geqs (pb, e);
  2442. else
  2443. omega_delete_variable (pb, i);
  2444. }
  2445. else
  2446. {
  2447. omega_substitute (pb, sub, i, c);
  2448. omega_delete_variable (pb, i);
  2449. }
  2450. }
  2451. else
  2452. {
  2453. int a = abs (c);
  2454. int e2 = e;
  2455. if (dump_file && (dump_flags & TDF_DETAILS))
  2456. fprintf (dump_file, "performing non-exact elimination, c = %d\n", c);
  2457. for (e = pb->num_eqs - 1; e >= 0; e--)
  2458. if (pb->eqs[e].coef[i])
  2459. {
  2460. eqn eqn = &(pb->eqs[e]);
  2461. int j, k;
  2462. for (j = n_vars; j >= 0; j--)
  2463. eqn->coef[j] *= a;
  2464. k = eqn->coef[i];
  2465. eqn->coef[i] = 0;
  2466. if (sub->color == omega_red)
  2467. eqn->color = omega_red;
  2468. for (j = n_vars; j >= 0; j--)
  2469. eqn->coef[j] -= sub->coef[j] * k / c;
  2470. }
  2471. for (e = pb->num_geqs - 1; e >= 0; e--)
  2472. if (pb->geqs[e].coef[i])
  2473. {
  2474. eqn eqn = &(pb->geqs[e]);
  2475. int j, k;
  2476. if (sub->color == omega_red)
  2477. eqn->color = omega_red;
  2478. for (j = n_vars; j >= 0; j--)
  2479. eqn->coef[j] *= a;
  2480. eqn->touched = 1;
  2481. k = eqn->coef[i];
  2482. eqn->coef[i] = 0;
  2483. for (j = n_vars; j >= 0; j--)
  2484. eqn->coef[j] -= sub->coef[j] * k / c;
  2485. }
  2486. for (e = pb->num_subs - 1; e >= 0; e--)
  2487. if (pb->subs[e].coef[i])
  2488. {
  2489. eqn eqn = &(pb->subs[e]);
  2490. int j, k;
  2491. gcc_assert (0);
  2492. gcc_assert (sub->color == omega_black);
  2493. for (j = n_vars; j >= 0; j--)
  2494. eqn->coef[j] *= a;
  2495. k = eqn->coef[i];
  2496. eqn->coef[i] = 0;
  2497. for (j = n_vars; j >= 0; j--)
  2498. eqn->coef[j] -= sub->coef[j] * k / c;
  2499. }
  2500. if (in_approximate_mode)
  2501. omega_delete_variable (pb, i);
  2502. else
  2503. omega_convert_eq_to_geqs (pb, e2);
  2504. }
  2505. omega_free_eqns (sub, 1);
  2506. }
  2507. /* Helper function for printing "sorry, no solution". */
  2508. static inline enum omega_result
  2509. omega_problem_has_no_solution (void)
  2510. {
  2511. if (dump_file && (dump_flags & TDF_DETAILS))
  2512. fprintf (dump_file, "\nequations have no solution \n");
  2513. return omega_false;
  2514. }
  2515. /* Helper function: solve equations in PB one at a time, following the
  2516. DESIRED_RES result. */
  2517. static enum omega_result
  2518. omega_solve_eq (omega_pb pb, enum omega_result desired_res)
  2519. {
  2520. int i, j, e;
  2521. int g, g2;
  2522. g = 0;
  2523. if (dump_file && (dump_flags & TDF_DETAILS) && pb->num_eqs > 0)
  2524. {
  2525. fprintf (dump_file, "\nomega_solve_eq (%d, %d)\n",
  2526. desired_res, may_be_red);
  2527. omega_print_problem (dump_file, pb);
  2528. fprintf (dump_file, "\n");
  2529. }
  2530. if (may_be_red)
  2531. {
  2532. i = 0;
  2533. j = pb->num_eqs - 1;
  2534. while (1)
  2535. {
  2536. eqn eq;
  2537. while (i <= j && pb->eqs[i].color == omega_red)
  2538. i++;
  2539. while (i <= j && pb->eqs[j].color == omega_black)
  2540. j--;
  2541. if (i >= j)
  2542. break;
  2543. eq = omega_alloc_eqns (0, 1);
  2544. omega_copy_eqn (eq, &pb->eqs[i], pb->num_vars);
  2545. omega_copy_eqn (&pb->eqs[i], &pb->eqs[j], pb->num_vars);
  2546. omega_copy_eqn (&pb->eqs[j], eq, pb->num_vars);
  2547. omega_free_eqns (eq, 1);
  2548. i++;
  2549. j--;
  2550. }
  2551. }
  2552. /* Eliminate all EQ equations */
  2553. for (e = pb->num_eqs - 1; e >= 0; e--)
  2554. {
  2555. eqn eqn = &(pb->eqs[e]);
  2556. int sv;
  2557. if (dump_file && (dump_flags & TDF_DETAILS))
  2558. fprintf (dump_file, "----\n");
  2559. for (i = pb->num_vars; i > 0; i--)
  2560. if (eqn->coef[i])
  2561. break;
  2562. g = eqn->coef[i];
  2563. for (j = i - 1; j > 0; j--)
  2564. if (eqn->coef[j])
  2565. break;
  2566. /* i is the position of last nonzero coefficient,
  2567. g is the coefficient of i,
  2568. j is the position of next nonzero coefficient. */
  2569. if (j == 0)
  2570. {
  2571. if (eqn->coef[0] % g != 0)
  2572. return omega_problem_has_no_solution ();
  2573. eqn->coef[0] = eqn->coef[0] / g;
  2574. eqn->coef[i] = 1;
  2575. pb->num_eqs--;
  2576. omega_do_elimination (pb, e, i);
  2577. continue;
  2578. }
  2579. else if (j == -1)
  2580. {
  2581. if (eqn->coef[0] != 0)
  2582. return omega_problem_has_no_solution ();
  2583. pb->num_eqs--;
  2584. continue;
  2585. }
  2586. if (g < 0)
  2587. g = -g;
  2588. if (g == 1)
  2589. {
  2590. pb->num_eqs--;
  2591. omega_do_elimination (pb, e, i);
  2592. }
  2593. else
  2594. {
  2595. int k = j;
  2596. bool promotion_possible =
  2597. (omega_safe_var_p (pb, j)
  2598. && pb->safe_vars + 1 == i
  2599. && !omega_eqn_is_red (eqn, desired_res)
  2600. && !in_approximate_mode);
  2601. if (dump_file && (dump_flags & TDF_DETAILS) && promotion_possible)
  2602. fprintf (dump_file, " Promotion possible\n");
  2603. normalizeEQ:
  2604. if (!omega_safe_var_p (pb, j))
  2605. {
  2606. for (; g != 1 && !omega_safe_var_p (pb, j); j--)
  2607. g = gcd (abs (eqn->coef[j]), g);
  2608. g2 = g;
  2609. }
  2610. else if (!omega_safe_var_p (pb, i))
  2611. g2 = g;
  2612. else
  2613. g2 = 0;
  2614. for (; g != 1 && j > 0; j--)
  2615. g = gcd (abs (eqn->coef[j]), g);
  2616. if (g > 1)
  2617. {
  2618. if (eqn->coef[0] % g != 0)
  2619. return omega_problem_has_no_solution ();
  2620. for (j = 0; j <= pb->num_vars; j++)
  2621. eqn->coef[j] /= g;
  2622. g2 = g2 / g;
  2623. }
  2624. if (g2 > 1)
  2625. {
  2626. int e2;
  2627. for (e2 = e - 1; e2 >= 0; e2--)
  2628. if (pb->eqs[e2].coef[i])
  2629. break;
  2630. if (e2 == -1)
  2631. for (e2 = pb->num_geqs - 1; e2 >= 0; e2--)
  2632. if (pb->geqs[e2].coef[i])
  2633. break;
  2634. if (e2 == -1)
  2635. for (e2 = pb->num_subs - 1; e2 >= 0; e2--)
  2636. if (pb->subs[e2].coef[i])
  2637. break;
  2638. if (e2 == -1)
  2639. {
  2640. bool change = false;
  2641. if (dump_file && (dump_flags & TDF_DETAILS))
  2642. {
  2643. fprintf (dump_file, "Ha! We own it! \n");
  2644. omega_print_eq (dump_file, pb, eqn);
  2645. fprintf (dump_file, " \n");
  2646. }
  2647. g = eqn->coef[i];
  2648. g = abs (g);
  2649. for (j = i - 1; j >= 0; j--)
  2650. {
  2651. int t = int_mod (eqn->coef[j], g);
  2652. if (2 * t >= g)
  2653. t -= g;
  2654. if (t != eqn->coef[j])
  2655. {
  2656. eqn->coef[j] = t;
  2657. change = true;
  2658. }
  2659. }
  2660. if (!change)
  2661. {
  2662. if (dump_file && (dump_flags & TDF_DETAILS))
  2663. fprintf (dump_file, "So what?\n");
  2664. }
  2665. else
  2666. {
  2667. omega_name_wild_card (pb, i);
  2668. if (dump_file && (dump_flags & TDF_DETAILS))
  2669. {
  2670. omega_print_eq (dump_file, pb, eqn);
  2671. fprintf (dump_file, " \n");
  2672. }
  2673. e++;
  2674. continue;
  2675. }
  2676. }
  2677. }
  2678. if (promotion_possible)
  2679. {
  2680. if (dump_file && (dump_flags & TDF_DETAILS))
  2681. {
  2682. fprintf (dump_file, "promoting %s to safety\n",
  2683. omega_variable_to_str (pb, i));
  2684. omega_print_vars (dump_file, pb);
  2685. }
  2686. pb->safe_vars++;
  2687. if (!omega_wildcard_p (pb, i))
  2688. omega_name_wild_card (pb, i);
  2689. promotion_possible = false;
  2690. j = k;
  2691. goto normalizeEQ;
  2692. }
  2693. if (g2 > 1 && !in_approximate_mode)
  2694. {
  2695. if (pb->eqs[e].color == omega_red)
  2696. {
  2697. if (dump_file && (dump_flags & TDF_DETAILS))
  2698. fprintf (dump_file, "handling red equality\n");
  2699. pb->num_eqs--;
  2700. omega_do_elimination (pb, e, i);
  2701. continue;
  2702. }
  2703. if (dump_file && (dump_flags & TDF_DETAILS))
  2704. {
  2705. fprintf (dump_file,
  2706. "adding equation to handle safe variable \n");
  2707. omega_print_eq (dump_file, pb, eqn);
  2708. fprintf (dump_file, "\n----\n");
  2709. omega_print_problem (dump_file, pb);
  2710. fprintf (dump_file, "\n----\n");
  2711. fprintf (dump_file, "\n----\n");
  2712. }
  2713. i = omega_add_new_wild_card (pb);
  2714. pb->num_eqs++;
  2715. gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
  2716. omega_init_eqn_zero (&pb->eqs[e + 1], pb->num_vars);
  2717. omega_copy_eqn (&pb->eqs[e + 1], eqn, pb->safe_vars);
  2718. for (j = pb->num_vars; j >= 0; j--)
  2719. {
  2720. pb->eqs[e + 1].coef[j] = int_mod (pb->eqs[e + 1].coef[j], g2);
  2721. if (2 * pb->eqs[e + 1].coef[j] >= g2)
  2722. pb->eqs[e + 1].coef[j] -= g2;
  2723. }
  2724. pb->eqs[e + 1].coef[i] = g2;
  2725. e += 2;
  2726. if (dump_file && (dump_flags & TDF_DETAILS))
  2727. omega_print_problem (dump_file, pb);
  2728. continue;
  2729. }
  2730. sv = pb->safe_vars;
  2731. if (g2 == 0)
  2732. sv = 0;
  2733. /* Find variable to eliminate. */
  2734. if (g2 > 1)
  2735. {
  2736. gcc_assert (in_approximate_mode);
  2737. if (dump_file && (dump_flags & TDF_DETAILS))
  2738. {
  2739. fprintf (dump_file, "non-exact elimination: ");
  2740. omega_print_eq (dump_file, pb, eqn);
  2741. fprintf (dump_file, "\n");
  2742. omega_print_problem (dump_file, pb);
  2743. }
  2744. for (i = pb->num_vars; i > sv; i--)
  2745. if (pb->eqs[e].coef[i] != 0)
  2746. break;
  2747. }
  2748. else
  2749. for (i = pb->num_vars; i > sv; i--)
  2750. if (pb->eqs[e].coef[i] == 1 || pb->eqs[e].coef[i] == -1)
  2751. break;
  2752. if (i > sv)
  2753. {
  2754. pb->num_eqs--;
  2755. omega_do_elimination (pb, e, i);
  2756. if (dump_file && (dump_flags & TDF_DETAILS) && g2 > 1)
  2757. {
  2758. fprintf (dump_file, "result of non-exact elimination:\n");
  2759. omega_print_problem (dump_file, pb);
  2760. }
  2761. }
  2762. else
  2763. {
  2764. int factor = (INT_MAX);
  2765. j = 0;
  2766. if (dump_file && (dump_flags & TDF_DETAILS))
  2767. fprintf (dump_file, "doing moding\n");
  2768. for (i = pb->num_vars; i != sv; i--)
  2769. if ((pb->eqs[e].coef[i] & 1) != 0)
  2770. {
  2771. j = i;
  2772. i--;
  2773. for (; i != sv; i--)
  2774. if ((pb->eqs[e].coef[i] & 1) != 0)
  2775. break;
  2776. break;
  2777. }
  2778. if (j != 0 && i == sv)
  2779. {
  2780. omega_do_mod (pb, 2, e, j);
  2781. e++;
  2782. continue;
  2783. }
  2784. j = 0;
  2785. for (i = pb->num_vars; i != sv; i--)
  2786. if (pb->eqs[e].coef[i] != 0
  2787. && factor > abs (pb->eqs[e].coef[i]) + 1)
  2788. {
  2789. factor = abs (pb->eqs[e].coef[i]) + 1;
  2790. j = i;
  2791. }
  2792. if (j == sv)
  2793. {
  2794. if (dump_file && (dump_flags & TDF_DETAILS))
  2795. fprintf (dump_file, "should not have happened\n");
  2796. gcc_assert (0);
  2797. }
  2798. omega_do_mod (pb, factor, e, j);
  2799. /* Go back and try this equation again. */
  2800. e++;
  2801. }
  2802. }
  2803. }
  2804. pb->num_eqs = 0;
  2805. return omega_unknown;
  2806. }
  2807. /* Transform an inequation E to an equality, then solve DIFF problems
  2808. based on PB, and only differing by the constant part that is
  2809. diminished by one, trying to figure out which of the constants
  2810. satisfies PB. */
  2811. static enum omega_result
  2812. parallel_splinter (omega_pb pb, int e, int diff,
  2813. enum omega_result desired_res)
  2814. {
  2815. omega_pb tmp_problem;
  2816. int i;
  2817. if (dump_file && (dump_flags & TDF_DETAILS))
  2818. {
  2819. fprintf (dump_file, "Using parallel splintering\n");
  2820. omega_print_problem (dump_file, pb);
  2821. }
  2822. tmp_problem = XNEW (struct omega_pb_d);
  2823. omega_copy_eqn (&pb->eqs[0], &pb->geqs[e], pb->num_vars);
  2824. pb->num_eqs = 1;
  2825. for (i = 0; i <= diff; i++)
  2826. {
  2827. omega_copy_problem (tmp_problem, pb);
  2828. if (dump_file && (dump_flags & TDF_DETAILS))
  2829. {
  2830. fprintf (dump_file, "Splinter # %i\n", i);
  2831. omega_print_problem (dump_file, pb);
  2832. }
  2833. if (omega_solve_problem (tmp_problem, desired_res) == omega_true)
  2834. {
  2835. free (tmp_problem);
  2836. return omega_true;
  2837. }
  2838. pb->eqs[0].coef[0]--;
  2839. }
  2840. free (tmp_problem);
  2841. return omega_false;
  2842. }
  2843. /* Helper function: solve equations one at a time. */
  2844. static enum omega_result
  2845. omega_solve_geq (omega_pb pb, enum omega_result desired_res)
  2846. {
  2847. int i, e;
  2848. int n_vars, fv;
  2849. enum omega_result result;
  2850. bool coupled_subscripts = false;
  2851. bool smoothed = false;
  2852. bool eliminate_again;
  2853. bool tried_eliminating_redundant = false;
  2854. if (desired_res != omega_simplify)
  2855. {
  2856. pb->num_subs = 0;
  2857. pb->safe_vars = 0;
  2858. }
  2859. solve_geq_start:
  2860. do {
  2861. gcc_assert (desired_res == omega_simplify || pb->num_subs == 0);
  2862. /* Verify that there are not too many inequalities. */
  2863. gcc_assert (pb->num_geqs <= OMEGA_MAX_GEQS);
  2864. if (dump_file && (dump_flags & TDF_DETAILS))
  2865. {
  2866. fprintf (dump_file, "\nomega_solve_geq (%d,%d):\n",
  2867. desired_res, please_no_equalities_in_simplified_problems);
  2868. omega_print_problem (dump_file, pb);
  2869. fprintf (dump_file, "\n");
  2870. }
  2871. n_vars = pb->num_vars;
  2872. if (n_vars == 1)
  2873. {
  2874. enum omega_eqn_color u_color = omega_black;
  2875. enum omega_eqn_color l_color = omega_black;
  2876. int upper_bound = pos_infinity;
  2877. int lower_bound = neg_infinity;
  2878. for (e = pb->num_geqs - 1; e >= 0; e--)
  2879. {
  2880. int a = pb->geqs[e].coef[1];
  2881. int c = pb->geqs[e].coef[0];
  2882. /* Our equation is ax + c >= 0, or ax >= -c, or c >= -ax. */
  2883. if (a == 0)
  2884. {
  2885. if (c < 0)
  2886. return omega_problem_has_no_solution ();
  2887. }
  2888. else if (a > 0)
  2889. {
  2890. if (a != 1)
  2891. c = int_div (c, a);
  2892. if (lower_bound < -c
  2893. || (lower_bound == -c
  2894. && !omega_eqn_is_red (&pb->geqs[e], desired_res)))
  2895. {
  2896. lower_bound = -c;
  2897. l_color = pb->geqs[e].color;
  2898. }
  2899. }
  2900. else
  2901. {
  2902. if (a != -1)
  2903. c = int_div (c, -a);
  2904. if (upper_bound > c
  2905. || (upper_bound == c
  2906. && !omega_eqn_is_red (&pb->geqs[e], desired_res)))
  2907. {
  2908. upper_bound = c;
  2909. u_color = pb->geqs[e].color;
  2910. }
  2911. }
  2912. }
  2913. if (dump_file && (dump_flags & TDF_DETAILS))
  2914. {
  2915. fprintf (dump_file, "upper bound = %d\n", upper_bound);
  2916. fprintf (dump_file, "lower bound = %d\n", lower_bound);
  2917. }
  2918. if (lower_bound > upper_bound)
  2919. return omega_problem_has_no_solution ();
  2920. if (desired_res == omega_simplify)
  2921. {
  2922. pb->num_geqs = 0;
  2923. if (pb->safe_vars == 1)
  2924. {
  2925. if (lower_bound == upper_bound
  2926. && u_color == omega_black
  2927. && l_color == omega_black)
  2928. {
  2929. pb->eqs[0].coef[0] = -lower_bound;
  2930. pb->eqs[0].coef[1] = 1;
  2931. pb->eqs[0].color = omega_black;
  2932. pb->num_eqs = 1;
  2933. return omega_solve_problem (pb, desired_res);
  2934. }
  2935. else
  2936. {
  2937. if (lower_bound > neg_infinity)
  2938. {
  2939. pb->geqs[0].coef[0] = -lower_bound;
  2940. pb->geqs[0].coef[1] = 1;
  2941. pb->geqs[0].key = 1;
  2942. pb->geqs[0].color = l_color;
  2943. pb->geqs[0].touched = 0;
  2944. pb->num_geqs = 1;
  2945. }
  2946. if (upper_bound < pos_infinity)
  2947. {
  2948. pb->geqs[pb->num_geqs].coef[0] = upper_bound;
  2949. pb->geqs[pb->num_geqs].coef[1] = -1;
  2950. pb->geqs[pb->num_geqs].key = -1;
  2951. pb->geqs[pb->num_geqs].color = u_color;
  2952. pb->geqs[pb->num_geqs].touched = 0;
  2953. pb->num_geqs++;
  2954. }
  2955. }
  2956. }
  2957. else
  2958. pb->num_vars = 0;
  2959. omega_problem_reduced (pb);
  2960. return omega_false;
  2961. }
  2962. if (original_problem != no_problem
  2963. && l_color == omega_black
  2964. && u_color == omega_black
  2965. && !conservative
  2966. && lower_bound == upper_bound)
  2967. {
  2968. pb->eqs[0].coef[0] = -lower_bound;
  2969. pb->eqs[0].coef[1] = 1;
  2970. pb->num_eqs = 1;
  2971. adding_equality_constraint (pb, 0);
  2972. }
  2973. return omega_true;
  2974. }
  2975. if (!pb->variables_freed)
  2976. {
  2977. pb->variables_freed = true;
  2978. if (desired_res != omega_simplify)
  2979. omega_free_eliminations (pb, 0);
  2980. else
  2981. omega_free_eliminations (pb, pb->safe_vars);
  2982. n_vars = pb->num_vars;
  2983. if (n_vars == 1)
  2984. continue;
  2985. }
  2986. switch (normalize_omega_problem (pb))
  2987. {
  2988. case normalize_false:
  2989. return omega_false;
  2990. break;
  2991. case normalize_coupled:
  2992. coupled_subscripts = true;
  2993. break;
  2994. case normalize_uncoupled:
  2995. coupled_subscripts = false;
  2996. break;
  2997. default:
  2998. gcc_unreachable ();
  2999. }
  3000. n_vars = pb->num_vars;
  3001. if (dump_file && (dump_flags & TDF_DETAILS))
  3002. {
  3003. fprintf (dump_file, "\nafter normalization:\n");
  3004. omega_print_problem (dump_file, pb);
  3005. fprintf (dump_file, "\n");
  3006. fprintf (dump_file, "eliminating variable using Fourier-Motzkin.\n");
  3007. }
  3008. do {
  3009. int parallel_difference = INT_MAX;
  3010. int best_parallel_eqn = -1;
  3011. int minC, maxC, minCj = 0;
  3012. int lower_bound_count = 0;
  3013. int e2, Le = 0, Ue;
  3014. bool possible_easy_int_solution;
  3015. int max_splinters = 1;
  3016. bool exact = false;
  3017. bool lucky_exact = false;
  3018. int best = (INT_MAX);
  3019. int j = 0, jLe = 0, jLowerBoundCount = 0;
  3020. eliminate_again = false;
  3021. if (pb->num_eqs > 0)
  3022. return omega_solve_problem (pb, desired_res);
  3023. if (!coupled_subscripts)
  3024. {
  3025. if (pb->safe_vars == 0)
  3026. pb->num_geqs = 0;
  3027. else
  3028. for (e = pb->num_geqs - 1; e >= 0; e--)
  3029. if (!omega_safe_var_p (pb, abs (pb->geqs[e].key)))
  3030. omega_delete_geq (pb, e, n_vars);
  3031. pb->num_vars = pb->safe_vars;
  3032. if (desired_res == omega_simplify)
  3033. {
  3034. omega_problem_reduced (pb);
  3035. return omega_false;
  3036. }
  3037. return omega_true;
  3038. }
  3039. if (desired_res != omega_simplify)
  3040. fv = 0;
  3041. else
  3042. fv = pb->safe_vars;
  3043. if (pb->num_geqs == 0)
  3044. {
  3045. if (desired_res == omega_simplify)
  3046. {
  3047. pb->num_vars = pb->safe_vars;
  3048. omega_problem_reduced (pb);
  3049. return omega_false;
  3050. }
  3051. return omega_true;
  3052. }
  3053. if (desired_res == omega_simplify && n_vars == pb->safe_vars)
  3054. {
  3055. omega_problem_reduced (pb);
  3056. return omega_false;
  3057. }
  3058. if (pb->num_geqs > OMEGA_MAX_GEQS - 30
  3059. || pb->num_geqs > 2 * n_vars * n_vars + 4 * n_vars + 10)
  3060. {
  3061. if (dump_file && (dump_flags & TDF_DETAILS))
  3062. fprintf (dump_file,
  3063. "TOO MANY EQUATIONS; "
  3064. "%d equations, %d variables, "
  3065. "ELIMINATING REDUNDANT ONES\n",
  3066. pb->num_geqs, n_vars);
  3067. if (!omega_eliminate_redundant (pb, false))
  3068. return omega_false;
  3069. n_vars = pb->num_vars;
  3070. if (pb->num_eqs > 0)
  3071. return omega_solve_problem (pb, desired_res);
  3072. if (dump_file && (dump_flags & TDF_DETAILS))
  3073. fprintf (dump_file, "END ELIMINATION OF REDUNDANT EQUATIONS\n");
  3074. }
  3075. if (desired_res != omega_simplify)
  3076. fv = 0;
  3077. else
  3078. fv = pb->safe_vars;
  3079. for (i = n_vars; i != fv; i--)
  3080. {
  3081. int score;
  3082. int ub = -2;
  3083. int lb = -2;
  3084. bool lucky = false;
  3085. int upper_bound_count = 0;
  3086. lower_bound_count = 0;
  3087. minC = maxC = 0;
  3088. for (e = pb->num_geqs - 1; e >= 0; e--)
  3089. if (pb->geqs[e].coef[i] < 0)
  3090. {
  3091. minC = MIN (minC, pb->geqs[e].coef[i]);
  3092. upper_bound_count++;
  3093. if (pb->geqs[e].coef[i] < -1)
  3094. {
  3095. if (ub == -2)
  3096. ub = e;
  3097. else
  3098. ub = -1;
  3099. }
  3100. }
  3101. else if (pb->geqs[e].coef[i] > 0)
  3102. {
  3103. maxC = MAX (maxC, pb->geqs[e].coef[i]);
  3104. lower_bound_count++;
  3105. Le = e;
  3106. if (pb->geqs[e].coef[i] > 1)
  3107. {
  3108. if (lb == -2)
  3109. lb = e;
  3110. else
  3111. lb = -1;
  3112. }
  3113. }
  3114. if (lower_bound_count == 0
  3115. || upper_bound_count == 0)
  3116. {
  3117. lower_bound_count = 0;
  3118. break;
  3119. }
  3120. if (ub >= 0 && lb >= 0
  3121. && pb->geqs[lb].key == -pb->geqs[ub].key)
  3122. {
  3123. int Lc = pb->geqs[lb].coef[i];
  3124. int Uc = -pb->geqs[ub].coef[i];
  3125. int diff =
  3126. Lc * pb->geqs[ub].coef[0] + Uc * pb->geqs[lb].coef[0];
  3127. lucky = (diff >= (Uc - 1) * (Lc - 1));
  3128. }
  3129. if (maxC == 1
  3130. || minC == -1
  3131. || lucky
  3132. || in_approximate_mode)
  3133. {
  3134. score = upper_bound_count * lower_bound_count;
  3135. if (dump_file && (dump_flags & TDF_DETAILS))
  3136. fprintf (dump_file,
  3137. "For %s, exact, score = %d*%d, range = %d ... %d,"
  3138. "\nlucky = %d, in_approximate_mode=%d \n",
  3139. omega_variable_to_str (pb, i),
  3140. upper_bound_count,
  3141. lower_bound_count, minC, maxC, lucky,
  3142. in_approximate_mode);
  3143. if (!exact
  3144. || score < best)
  3145. {
  3146. best = score;
  3147. j = i;
  3148. minCj = minC;
  3149. jLe = Le;
  3150. jLowerBoundCount = lower_bound_count;
  3151. exact = true;
  3152. lucky_exact = lucky;
  3153. if (score == 1)
  3154. break;
  3155. }
  3156. }
  3157. else if (!exact)
  3158. {
  3159. if (dump_file && (dump_flags & TDF_DETAILS))
  3160. fprintf (dump_file,
  3161. "For %s, non-exact, score = %d*%d,"
  3162. "range = %d ... %d \n",
  3163. omega_variable_to_str (pb, i),
  3164. upper_bound_count,
  3165. lower_bound_count, minC, maxC);
  3166. score = maxC - minC;
  3167. if (best > score)
  3168. {
  3169. best = score;
  3170. j = i;
  3171. minCj = minC;
  3172. jLe = Le;
  3173. jLowerBoundCount = lower_bound_count;
  3174. }
  3175. }
  3176. }
  3177. if (lower_bound_count == 0)
  3178. {
  3179. omega_free_eliminations (pb, pb->safe_vars);
  3180. n_vars = pb->num_vars;
  3181. eliminate_again = true;
  3182. continue;
  3183. }
  3184. i = j;
  3185. minC = minCj;
  3186. Le = jLe;
  3187. lower_bound_count = jLowerBoundCount;
  3188. for (e = pb->num_geqs - 1; e >= 0; e--)
  3189. if (pb->geqs[e].coef[i] > 0)
  3190. {
  3191. if (pb->geqs[e].coef[i] == -minC)
  3192. max_splinters += -minC - 1;
  3193. else
  3194. max_splinters +=
  3195. pos_mul_hwi ((pb->geqs[e].coef[i] - 1),
  3196. (-minC - 1)) / (-minC) + 1;
  3197. }
  3198. /* #ifdef Omega3 */
  3199. /* Trying to produce exact elimination by finding redundant
  3200. constraints. */
  3201. if (!exact && !tried_eliminating_redundant)
  3202. {
  3203. omega_eliminate_redundant (pb, false);
  3204. tried_eliminating_redundant = true;
  3205. eliminate_again = true;
  3206. continue;
  3207. }
  3208. tried_eliminating_redundant = false;
  3209. /* #endif */
  3210. if (return_single_result && desired_res == omega_simplify && !exact)
  3211. {
  3212. omega_problem_reduced (pb);
  3213. return omega_true;
  3214. }
  3215. /* #ifndef Omega3 */
  3216. /* Trying to produce exact elimination by finding redundant
  3217. constraints. */
  3218. if (!exact && !tried_eliminating_redundant)
  3219. {
  3220. omega_eliminate_redundant (pb, false);
  3221. tried_eliminating_redundant = true;
  3222. continue;
  3223. }
  3224. tried_eliminating_redundant = false;
  3225. /* #endif */
  3226. if (!exact)
  3227. {
  3228. int e1, e2;
  3229. for (e1 = pb->num_geqs - 1; e1 >= 0; e1--)
  3230. if (pb->geqs[e1].color == omega_black)
  3231. for (e2 = e1 - 1; e2 >= 0; e2--)
  3232. if (pb->geqs[e2].color == omega_black
  3233. && pb->geqs[e1].key == -pb->geqs[e2].key
  3234. && ((pb->geqs[e1].coef[0] + pb->geqs[e2].coef[0])
  3235. * (3 - single_var_geq (&pb->geqs[e1], pb->num_vars))
  3236. / 2 < parallel_difference))
  3237. {
  3238. parallel_difference =
  3239. (pb->geqs[e1].coef[0] + pb->geqs[e2].coef[0])
  3240. * (3 - single_var_geq (&pb->geqs[e1], pb->num_vars))
  3241. / 2;
  3242. best_parallel_eqn = e1;
  3243. }
  3244. if (dump_file && (dump_flags & TDF_DETAILS)
  3245. && best_parallel_eqn >= 0)
  3246. {
  3247. fprintf (dump_file,
  3248. "Possible parallel projection, diff = %d, in ",
  3249. parallel_difference);
  3250. omega_print_geq (dump_file, pb, &(pb->geqs[best_parallel_eqn]));
  3251. fprintf (dump_file, "\n");
  3252. omega_print_problem (dump_file, pb);
  3253. }
  3254. }
  3255. if (dump_file && (dump_flags & TDF_DETAILS))
  3256. {
  3257. fprintf (dump_file, "going to eliminate %s, (%d,%d,%d)\n",
  3258. omega_variable_to_str (pb, i), i, minC,
  3259. lower_bound_count);
  3260. omega_print_problem (dump_file, pb);
  3261. if (lucky_exact)
  3262. fprintf (dump_file, "(a lucky exact elimination)\n");
  3263. else if (exact)
  3264. fprintf (dump_file, "(an exact elimination)\n");
  3265. fprintf (dump_file, "Max # of splinters = %d\n", max_splinters);
  3266. }
  3267. gcc_assert (max_splinters >= 1);
  3268. if (!exact && desired_res == omega_simplify && best_parallel_eqn >= 0
  3269. && parallel_difference <= max_splinters)
  3270. return parallel_splinter (pb, best_parallel_eqn, parallel_difference,
  3271. desired_res);
  3272. smoothed = false;
  3273. if (i != n_vars)
  3274. {
  3275. int t;
  3276. int j = pb->num_vars;
  3277. if (dump_file && (dump_flags & TDF_DETAILS))
  3278. {
  3279. fprintf (dump_file, "Swapping %d and %d\n", i, j);
  3280. omega_print_problem (dump_file, pb);
  3281. }
  3282. swap (&pb->var[i], &pb->var[j]);
  3283. for (e = pb->num_geqs - 1; e >= 0; e--)
  3284. if (pb->geqs[e].coef[i] != pb->geqs[e].coef[j])
  3285. {
  3286. pb->geqs[e].touched = 1;
  3287. t = pb->geqs[e].coef[i];
  3288. pb->geqs[e].coef[i] = pb->geqs[e].coef[j];
  3289. pb->geqs[e].coef[j] = t;
  3290. }
  3291. for (e = pb->num_subs - 1; e >= 0; e--)
  3292. if (pb->subs[e].coef[i] != pb->subs[e].coef[j])
  3293. {
  3294. t = pb->subs[e].coef[i];
  3295. pb->subs[e].coef[i] = pb->subs[e].coef[j];
  3296. pb->subs[e].coef[j] = t;
  3297. }
  3298. if (dump_file && (dump_flags & TDF_DETAILS))
  3299. {
  3300. fprintf (dump_file, "Swapping complete \n");
  3301. omega_print_problem (dump_file, pb);
  3302. fprintf (dump_file, "\n");
  3303. }
  3304. i = j;
  3305. }
  3306. else if (dump_file && (dump_flags & TDF_DETAILS))
  3307. {
  3308. fprintf (dump_file, "No swap needed\n");
  3309. omega_print_problem (dump_file, pb);
  3310. }
  3311. pb->num_vars--;
  3312. n_vars = pb->num_vars;
  3313. if (exact)
  3314. {
  3315. if (n_vars == 1)
  3316. {
  3317. int upper_bound = pos_infinity;
  3318. int lower_bound = neg_infinity;
  3319. enum omega_eqn_color ub_color = omega_black;
  3320. enum omega_eqn_color lb_color = omega_black;
  3321. int topeqn = pb->num_geqs - 1;
  3322. int Lc = pb->geqs[Le].coef[i];
  3323. for (Le = topeqn; Le >= 0; Le--)
  3324. if ((Lc = pb->geqs[Le].coef[i]) == 0)
  3325. {
  3326. if (pb->geqs[Le].coef[1] == 1)
  3327. {
  3328. int constantTerm = -pb->geqs[Le].coef[0];
  3329. if (constantTerm > lower_bound ||
  3330. (constantTerm == lower_bound &&
  3331. !omega_eqn_is_red (&pb->geqs[Le], desired_res)))
  3332. {
  3333. lower_bound = constantTerm;
  3334. lb_color = pb->geqs[Le].color;
  3335. }
  3336. if (dump_file && (dump_flags & TDF_DETAILS))
  3337. {
  3338. if (pb->geqs[Le].color == omega_black)
  3339. fprintf (dump_file, " :::=> %s >= %d\n",
  3340. omega_variable_to_str (pb, 1),
  3341. constantTerm);
  3342. else
  3343. fprintf (dump_file,
  3344. " :::=> [%s >= %d]\n",
  3345. omega_variable_to_str (pb, 1),
  3346. constantTerm);
  3347. }
  3348. }
  3349. else
  3350. {
  3351. int constantTerm = pb->geqs[Le].coef[0];
  3352. if (constantTerm < upper_bound ||
  3353. (constantTerm == upper_bound
  3354. && !omega_eqn_is_red (&pb->geqs[Le],
  3355. desired_res)))
  3356. {
  3357. upper_bound = constantTerm;
  3358. ub_color = pb->geqs[Le].color;
  3359. }
  3360. if (dump_file && (dump_flags & TDF_DETAILS))
  3361. {
  3362. if (pb->geqs[Le].color == omega_black)
  3363. fprintf (dump_file, " :::=> %s <= %d\n",
  3364. omega_variable_to_str (pb, 1),
  3365. constantTerm);
  3366. else
  3367. fprintf (dump_file,
  3368. " :::=> [%s <= %d]\n",
  3369. omega_variable_to_str (pb, 1),
  3370. constantTerm);
  3371. }
  3372. }
  3373. }
  3374. else if (Lc > 0)
  3375. for (Ue = topeqn; Ue >= 0; Ue--)
  3376. if (pb->geqs[Ue].coef[i] < 0
  3377. && pb->geqs[Le].key != -pb->geqs[Ue].key)
  3378. {
  3379. int Uc = -pb->geqs[Ue].coef[i];
  3380. int coefficient = pb->geqs[Ue].coef[1] * Lc
  3381. + pb->geqs[Le].coef[1] * Uc;
  3382. int constantTerm = pb->geqs[Ue].coef[0] * Lc
  3383. + pb->geqs[Le].coef[0] * Uc;
  3384. if (dump_file && (dump_flags & TDF_DETAILS))
  3385. {
  3386. omega_print_geq_extra (dump_file, pb,
  3387. &(pb->geqs[Ue]));
  3388. fprintf (dump_file, "\n");
  3389. omega_print_geq_extra (dump_file, pb,
  3390. &(pb->geqs[Le]));
  3391. fprintf (dump_file, "\n");
  3392. }
  3393. if (coefficient > 0)
  3394. {
  3395. constantTerm = -int_div (constantTerm, coefficient);
  3396. if (constantTerm > lower_bound
  3397. || (constantTerm == lower_bound
  3398. && (desired_res != omega_simplify
  3399. || (pb->geqs[Ue].color == omega_black
  3400. && pb->geqs[Le].color == omega_black))))
  3401. {
  3402. lower_bound = constantTerm;
  3403. lb_color = (pb->geqs[Ue].color == omega_red
  3404. || pb->geqs[Le].color == omega_red)
  3405. ? omega_red : omega_black;
  3406. }
  3407. if (dump_file && (dump_flags & TDF_DETAILS))
  3408. {
  3409. if (pb->geqs[Ue].color == omega_red
  3410. || pb->geqs[Le].color == omega_red)
  3411. fprintf (dump_file,
  3412. " ::=> [%s >= %d]\n",
  3413. omega_variable_to_str (pb, 1),
  3414. constantTerm);
  3415. else
  3416. fprintf (dump_file,
  3417. " ::=> %s >= %d\n",
  3418. omega_variable_to_str (pb, 1),
  3419. constantTerm);
  3420. }
  3421. }
  3422. else
  3423. {
  3424. constantTerm = int_div (constantTerm, -coefficient);
  3425. if (constantTerm < upper_bound
  3426. || (constantTerm == upper_bound
  3427. && pb->geqs[Ue].color == omega_black
  3428. && pb->geqs[Le].color == omega_black))
  3429. {
  3430. upper_bound = constantTerm;
  3431. ub_color = (pb->geqs[Ue].color == omega_red
  3432. || pb->geqs[Le].color == omega_red)
  3433. ? omega_red : omega_black;
  3434. }
  3435. if (dump_file
  3436. && (dump_flags & TDF_DETAILS))
  3437. {
  3438. if (pb->geqs[Ue].color == omega_red
  3439. || pb->geqs[Le].color == omega_red)
  3440. fprintf (dump_file,
  3441. " ::=> [%s <= %d]\n",
  3442. omega_variable_to_str (pb, 1),
  3443. constantTerm);
  3444. else
  3445. fprintf (dump_file,
  3446. " ::=> %s <= %d\n",
  3447. omega_variable_to_str (pb, 1),
  3448. constantTerm);
  3449. }
  3450. }
  3451. }
  3452. pb->num_geqs = 0;
  3453. if (dump_file && (dump_flags & TDF_DETAILS))
  3454. fprintf (dump_file,
  3455. " therefore, %c%d <= %c%s%c <= %d%c\n",
  3456. lb_color == omega_red ? '[' : ' ', lower_bound,
  3457. (lb_color == omega_red && ub_color == omega_black)
  3458. ? ']' : ' ',
  3459. omega_variable_to_str (pb, 1),
  3460. (lb_color == omega_black && ub_color == omega_red)
  3461. ? '[' : ' ',
  3462. upper_bound, ub_color == omega_red ? ']' : ' ');
  3463. if (lower_bound > upper_bound)
  3464. return omega_false;
  3465. if (pb->safe_vars == 1)
  3466. {
  3467. if (upper_bound == lower_bound
  3468. && !(ub_color == omega_red || lb_color == omega_red)
  3469. && !please_no_equalities_in_simplified_problems)
  3470. {
  3471. pb->num_eqs++;
  3472. pb->eqs[0].coef[1] = -1;
  3473. pb->eqs[0].coef[0] = upper_bound;
  3474. if (ub_color == omega_red
  3475. || lb_color == omega_red)
  3476. pb->eqs[0].color = omega_red;
  3477. if (desired_res == omega_simplify
  3478. && pb->eqs[0].color == omega_black)
  3479. return omega_solve_problem (pb, desired_res);
  3480. }
  3481. if (upper_bound != pos_infinity)
  3482. {
  3483. pb->geqs[0].coef[1] = -1;
  3484. pb->geqs[0].coef[0] = upper_bound;
  3485. pb->geqs[0].color = ub_color;
  3486. pb->geqs[0].key = -1;
  3487. pb->geqs[0].touched = 0;
  3488. pb->num_geqs++;
  3489. }
  3490. if (lower_bound != neg_infinity)
  3491. {
  3492. pb->geqs[pb->num_geqs].coef[1] = 1;
  3493. pb->geqs[pb->num_geqs].coef[0] = -lower_bound;
  3494. pb->geqs[pb->num_geqs].color = lb_color;
  3495. pb->geqs[pb->num_geqs].key = 1;
  3496. pb->geqs[pb->num_geqs].touched = 0;
  3497. pb->num_geqs++;
  3498. }
  3499. }
  3500. if (desired_res == omega_simplify)
  3501. {
  3502. omega_problem_reduced (pb);
  3503. return omega_false;
  3504. }
  3505. else
  3506. {
  3507. if (!conservative
  3508. && (desired_res != omega_simplify
  3509. || (lb_color == omega_black
  3510. && ub_color == omega_black))
  3511. && original_problem != no_problem
  3512. && lower_bound == upper_bound)
  3513. {
  3514. for (i = original_problem->num_vars; i >= 0; i--)
  3515. if (original_problem->var[i] == pb->var[1])
  3516. break;
  3517. if (i == 0)
  3518. break;
  3519. e = original_problem->num_eqs++;
  3520. omega_init_eqn_zero (&original_problem->eqs[e],
  3521. original_problem->num_vars);
  3522. original_problem->eqs[e].coef[i] = -1;
  3523. original_problem->eqs[e].coef[0] = upper_bound;
  3524. if (dump_file && (dump_flags & TDF_DETAILS))
  3525. {
  3526. fprintf (dump_file,
  3527. "adding equality %d to outer problem\n", e);
  3528. omega_print_problem (dump_file, original_problem);
  3529. }
  3530. }
  3531. return omega_true;
  3532. }
  3533. }
  3534. eliminate_again = true;
  3535. if (lower_bound_count == 1)
  3536. {
  3537. eqn lbeqn = omega_alloc_eqns (0, 1);
  3538. int Lc = pb->geqs[Le].coef[i];
  3539. if (dump_file && (dump_flags & TDF_DETAILS))
  3540. fprintf (dump_file, "an inplace elimination\n");
  3541. omega_copy_eqn (lbeqn, &pb->geqs[Le], (n_vars + 1));
  3542. omega_delete_geq_extra (pb, Le, n_vars + 1);
  3543. for (Ue = pb->num_geqs - 1; Ue >= 0; Ue--)
  3544. if (pb->geqs[Ue].coef[i] < 0)
  3545. {
  3546. if (lbeqn->key == -pb->geqs[Ue].key)
  3547. omega_delete_geq_extra (pb, Ue, n_vars + 1);
  3548. else
  3549. {
  3550. int k;
  3551. int Uc = -pb->geqs[Ue].coef[i];
  3552. pb->geqs[Ue].touched = 1;
  3553. eliminate_again = false;
  3554. if (lbeqn->color == omega_red)
  3555. pb->geqs[Ue].color = omega_red;
  3556. for (k = 0; k <= n_vars; k++)
  3557. pb->geqs[Ue].coef[k] =
  3558. mul_hwi (pb->geqs[Ue].coef[k], Lc) +
  3559. mul_hwi (lbeqn->coef[k], Uc);
  3560. if (dump_file && (dump_flags & TDF_DETAILS))
  3561. {
  3562. omega_print_geq (dump_file, pb,
  3563. &(pb->geqs[Ue]));
  3564. fprintf (dump_file, "\n");
  3565. }
  3566. }
  3567. }
  3568. omega_free_eqns (lbeqn, 1);
  3569. continue;
  3570. }
  3571. else
  3572. {
  3573. int *dead_eqns = XNEWVEC (int, OMEGA_MAX_GEQS);
  3574. bool *is_dead = XNEWVEC (bool, OMEGA_MAX_GEQS);
  3575. int num_dead = 0;
  3576. int top_eqn = pb->num_geqs - 1;
  3577. lower_bound_count--;
  3578. if (dump_file && (dump_flags & TDF_DETAILS))
  3579. fprintf (dump_file, "lower bound count = %d\n",
  3580. lower_bound_count);
  3581. for (Le = top_eqn; Le >= 0; Le--)
  3582. if (pb->geqs[Le].coef[i] > 0)
  3583. {
  3584. int Lc = pb->geqs[Le].coef[i];
  3585. for (Ue = top_eqn; Ue >= 0; Ue--)
  3586. if (pb->geqs[Ue].coef[i] < 0)
  3587. {
  3588. if (pb->geqs[Le].key != -pb->geqs[Ue].key)
  3589. {
  3590. int k;
  3591. int Uc = -pb->geqs[Ue].coef[i];
  3592. if (num_dead == 0)
  3593. e2 = pb->num_geqs++;
  3594. else
  3595. e2 = dead_eqns[--num_dead];
  3596. gcc_assert (e2 < OMEGA_MAX_GEQS);
  3597. if (dump_file && (dump_flags & TDF_DETAILS))
  3598. {
  3599. fprintf (dump_file,
  3600. "Le = %d, Ue = %d, gen = %d\n",
  3601. Le, Ue, e2);
  3602. omega_print_geq_extra (dump_file, pb,
  3603. &(pb->geqs[Le]));
  3604. fprintf (dump_file, "\n");
  3605. omega_print_geq_extra (dump_file, pb,
  3606. &(pb->geqs[Ue]));
  3607. fprintf (dump_file, "\n");
  3608. }
  3609. eliminate_again = false;
  3610. for (k = n_vars; k >= 0; k--)
  3611. pb->geqs[e2].coef[k] =
  3612. mul_hwi (pb->geqs[Ue].coef[k], Lc) +
  3613. mul_hwi (pb->geqs[Le].coef[k], Uc);
  3614. pb->geqs[e2].coef[n_vars + 1] = 0;
  3615. pb->geqs[e2].touched = 1;
  3616. if (pb->geqs[Ue].color == omega_red
  3617. || pb->geqs[Le].color == omega_red)
  3618. pb->geqs[e2].color = omega_red;
  3619. else
  3620. pb->geqs[e2].color = omega_black;
  3621. if (dump_file && (dump_flags & TDF_DETAILS))
  3622. {
  3623. omega_print_geq (dump_file, pb,
  3624. &(pb->geqs[e2]));
  3625. fprintf (dump_file, "\n");
  3626. }
  3627. }
  3628. if (lower_bound_count == 0)
  3629. {
  3630. dead_eqns[num_dead++] = Ue;
  3631. if (dump_file && (dump_flags & TDF_DETAILS))
  3632. fprintf (dump_file, "Killed %d\n", Ue);
  3633. }
  3634. }
  3635. lower_bound_count--;
  3636. dead_eqns[num_dead++] = Le;
  3637. if (dump_file && (dump_flags & TDF_DETAILS))
  3638. fprintf (dump_file, "Killed %d\n", Le);
  3639. }
  3640. for (e = pb->num_geqs - 1; e >= 0; e--)
  3641. is_dead[e] = false;
  3642. while (num_dead > 0)
  3643. is_dead[dead_eqns[--num_dead]] = true;
  3644. for (e = pb->num_geqs - 1; e >= 0; e--)
  3645. if (is_dead[e])
  3646. omega_delete_geq_extra (pb, e, n_vars + 1);
  3647. free (dead_eqns);
  3648. free (is_dead);
  3649. continue;
  3650. }
  3651. }
  3652. else
  3653. {
  3654. omega_pb rS, iS;
  3655. rS = omega_alloc_problem (0, 0);
  3656. iS = omega_alloc_problem (0, 0);
  3657. e2 = 0;
  3658. possible_easy_int_solution = true;
  3659. for (e = 0; e < pb->num_geqs; e++)
  3660. if (pb->geqs[e].coef[i] == 0)
  3661. {
  3662. omega_copy_eqn (&(rS->geqs[e2]), &pb->geqs[e],
  3663. pb->num_vars);
  3664. omega_copy_eqn (&(iS->geqs[e2]), &pb->geqs[e],
  3665. pb->num_vars);
  3666. if (dump_file && (dump_flags & TDF_DETAILS))
  3667. {
  3668. int t;
  3669. fprintf (dump_file, "Copying (%d, %d): ", i,
  3670. pb->geqs[e].coef[i]);
  3671. omega_print_geq_extra (dump_file, pb, &pb->geqs[e]);
  3672. fprintf (dump_file, "\n");
  3673. for (t = 0; t <= n_vars + 1; t++)
  3674. fprintf (dump_file, "%d ", pb->geqs[e].coef[t]);
  3675. fprintf (dump_file, "\n");
  3676. }
  3677. e2++;
  3678. gcc_assert (e2 < OMEGA_MAX_GEQS);
  3679. }
  3680. for (Le = pb->num_geqs - 1; Le >= 0; Le--)
  3681. if (pb->geqs[Le].coef[i] > 0)
  3682. for (Ue = pb->num_geqs - 1; Ue >= 0; Ue--)
  3683. if (pb->geqs[Ue].coef[i] < 0)
  3684. {
  3685. int k;
  3686. int Lc = pb->geqs[Le].coef[i];
  3687. int Uc = -pb->geqs[Ue].coef[i];
  3688. if (pb->geqs[Le].key != -pb->geqs[Ue].key)
  3689. {
  3690. rS->geqs[e2].touched = iS->geqs[e2].touched = 1;
  3691. if (dump_file && (dump_flags & TDF_DETAILS))
  3692. {
  3693. fprintf (dump_file, "---\n");
  3694. fprintf (dump_file,
  3695. "Le(Lc) = %d(%d_, Ue(Uc) = %d(%d), gen = %d\n",
  3696. Le, Lc, Ue, Uc, e2);
  3697. omega_print_geq_extra (dump_file, pb, &pb->geqs[Le]);
  3698. fprintf (dump_file, "\n");
  3699. omega_print_geq_extra (dump_file, pb, &pb->geqs[Ue]);
  3700. fprintf (dump_file, "\n");
  3701. }
  3702. if (Uc == Lc)
  3703. {
  3704. for (k = n_vars; k >= 0; k--)
  3705. iS->geqs[e2].coef[k] = rS->geqs[e2].coef[k] =
  3706. pb->geqs[Ue].coef[k] + pb->geqs[Le].coef[k];
  3707. iS->geqs[e2].coef[0] -= (Uc - 1);
  3708. }
  3709. else
  3710. {
  3711. for (k = n_vars; k >= 0; k--)
  3712. iS->geqs[e2].coef[k] = rS->geqs[e2].coef[k] =
  3713. mul_hwi (pb->geqs[Ue].coef[k], Lc) +
  3714. mul_hwi (pb->geqs[Le].coef[k], Uc);
  3715. iS->geqs[e2].coef[0] -= (Uc - 1) * (Lc - 1);
  3716. }
  3717. if (pb->geqs[Ue].color == omega_red
  3718. || pb->geqs[Le].color == omega_red)
  3719. iS->geqs[e2].color = rS->geqs[e2].color = omega_red;
  3720. else
  3721. iS->geqs[e2].color = rS->geqs[e2].color = omega_black;
  3722. if (dump_file && (dump_flags & TDF_DETAILS))
  3723. {
  3724. omega_print_geq (dump_file, pb, &(rS->geqs[e2]));
  3725. fprintf (dump_file, "\n");
  3726. }
  3727. e2++;
  3728. gcc_assert (e2 < OMEGA_MAX_GEQS);
  3729. }
  3730. else if (pb->geqs[Ue].coef[0] * Lc +
  3731. pb->geqs[Le].coef[0] * Uc -
  3732. (Uc - 1) * (Lc - 1) < 0)
  3733. possible_easy_int_solution = false;
  3734. }
  3735. iS->variables_initialized = rS->variables_initialized = true;
  3736. iS->num_vars = rS->num_vars = pb->num_vars;
  3737. iS->num_geqs = rS->num_geqs = e2;
  3738. iS->num_eqs = rS->num_eqs = 0;
  3739. iS->num_subs = rS->num_subs = pb->num_subs;
  3740. iS->safe_vars = rS->safe_vars = pb->safe_vars;
  3741. for (e = n_vars; e >= 0; e--)
  3742. rS->var[e] = pb->var[e];
  3743. for (e = n_vars; e >= 0; e--)
  3744. iS->var[e] = pb->var[e];
  3745. for (e = pb->num_subs - 1; e >= 0; e--)
  3746. {
  3747. omega_copy_eqn (&(rS->subs[e]), &(pb->subs[e]), pb->num_vars);
  3748. omega_copy_eqn (&(iS->subs[e]), &(pb->subs[e]), pb->num_vars);
  3749. }
  3750. pb->num_vars++;
  3751. n_vars = pb->num_vars;
  3752. if (desired_res != omega_true)
  3753. {
  3754. if (original_problem == no_problem)
  3755. {
  3756. original_problem = pb;
  3757. result = omega_solve_geq (rS, omega_false);
  3758. original_problem = no_problem;
  3759. }
  3760. else
  3761. result = omega_solve_geq (rS, omega_false);
  3762. if (result == omega_false)
  3763. {
  3764. free (rS);
  3765. free (iS);
  3766. return result;
  3767. }
  3768. if (pb->num_eqs > 0)
  3769. {
  3770. /* An equality constraint must have been found */
  3771. free (rS);
  3772. free (iS);
  3773. return omega_solve_problem (pb, desired_res);
  3774. }
  3775. }
  3776. if (desired_res != omega_false)
  3777. {
  3778. int j;
  3779. int lower_bounds = 0;
  3780. int *lower_bound = XNEWVEC (int, OMEGA_MAX_GEQS);
  3781. if (possible_easy_int_solution)
  3782. {
  3783. conservative++;
  3784. result = omega_solve_geq (iS, desired_res);
  3785. conservative--;
  3786. if (result != omega_false)
  3787. {
  3788. free (rS);
  3789. free (iS);
  3790. free (lower_bound);
  3791. return result;
  3792. }
  3793. }
  3794. if (!exact && best_parallel_eqn >= 0
  3795. && parallel_difference <= max_splinters)
  3796. {
  3797. free (rS);
  3798. free (iS);
  3799. free (lower_bound);
  3800. return parallel_splinter (pb, best_parallel_eqn,
  3801. parallel_difference,
  3802. desired_res);
  3803. }
  3804. if (dump_file && (dump_flags & TDF_DETAILS))
  3805. fprintf (dump_file, "have to do exact analysis\n");
  3806. conservative++;
  3807. for (e = 0; e < pb->num_geqs; e++)
  3808. if (pb->geqs[e].coef[i] > 1)
  3809. lower_bound[lower_bounds++] = e;
  3810. /* Sort array LOWER_BOUND. */
  3811. for (j = 0; j < lower_bounds; j++)
  3812. {
  3813. int k, smallest = j;
  3814. for (k = j + 1; k < lower_bounds; k++)
  3815. if (pb->geqs[lower_bound[smallest]].coef[i] >
  3816. pb->geqs[lower_bound[k]].coef[i])
  3817. smallest = k;
  3818. k = lower_bound[smallest];
  3819. lower_bound[smallest] = lower_bound[j];
  3820. lower_bound[j] = k;
  3821. }
  3822. if (dump_file && (dump_flags & TDF_DETAILS))
  3823. {
  3824. fprintf (dump_file, "lower bound coefficients = ");
  3825. for (j = 0; j < lower_bounds; j++)
  3826. fprintf (dump_file, " %d",
  3827. pb->geqs[lower_bound[j]].coef[i]);
  3828. fprintf (dump_file, "\n");
  3829. }
  3830. for (j = 0; j < lower_bounds; j++)
  3831. {
  3832. int max_incr;
  3833. int c;
  3834. int worst_lower_bound_constant = -minC;
  3835. e = lower_bound[j];
  3836. max_incr = (((pb->geqs[e].coef[i] - 1) *
  3837. (worst_lower_bound_constant - 1) - 1)
  3838. / worst_lower_bound_constant);
  3839. /* max_incr += 2; */
  3840. if (dump_file && (dump_flags & TDF_DETAILS))
  3841. {
  3842. fprintf (dump_file, "for equation ");
  3843. omega_print_geq (dump_file, pb, &pb->geqs[e]);
  3844. fprintf (dump_file,
  3845. "\ntry decrements from 0 to %d\n",
  3846. max_incr);
  3847. omega_print_problem (dump_file, pb);
  3848. }
  3849. if (max_incr > 50 && !smoothed
  3850. && smooth_weird_equations (pb))
  3851. {
  3852. conservative--;
  3853. free (rS);
  3854. free (iS);
  3855. smoothed = true;
  3856. goto solve_geq_start;
  3857. }
  3858. omega_copy_eqn (&pb->eqs[0], &pb->geqs[e],
  3859. pb->num_vars);
  3860. pb->eqs[0].color = omega_black;
  3861. omega_init_eqn_zero (&pb->geqs[e], pb->num_vars);
  3862. pb->geqs[e].touched = 1;
  3863. pb->num_eqs = 1;
  3864. for (c = max_incr; c >= 0; c--)
  3865. {
  3866. if (dump_file && (dump_flags & TDF_DETAILS))
  3867. {
  3868. fprintf (dump_file,
  3869. "trying next decrement of %d\n",
  3870. max_incr - c);
  3871. omega_print_problem (dump_file, pb);
  3872. }
  3873. omega_copy_problem (rS, pb);
  3874. if (dump_file && (dump_flags & TDF_DETAILS))
  3875. omega_print_problem (dump_file, rS);
  3876. result = omega_solve_problem (rS, desired_res);
  3877. if (result == omega_true)
  3878. {
  3879. free (rS);
  3880. free (iS);
  3881. free (lower_bound);
  3882. conservative--;
  3883. return omega_true;
  3884. }
  3885. pb->eqs[0].coef[0]--;
  3886. }
  3887. if (j + 1 < lower_bounds)
  3888. {
  3889. pb->num_eqs = 0;
  3890. omega_copy_eqn (&pb->geqs[e], &pb->eqs[0],
  3891. pb->num_vars);
  3892. pb->geqs[e].touched = 1;
  3893. pb->geqs[e].color = omega_black;
  3894. omega_copy_problem (rS, pb);
  3895. if (dump_file && (dump_flags & TDF_DETAILS))
  3896. fprintf (dump_file,
  3897. "exhausted lower bound, "
  3898. "checking if still feasible ");
  3899. result = omega_solve_problem (rS, omega_false);
  3900. if (result == omega_false)
  3901. break;
  3902. }
  3903. }
  3904. if (dump_file && (dump_flags & TDF_DETAILS))
  3905. fprintf (dump_file, "fall-off the end\n");
  3906. free (rS);
  3907. free (iS);
  3908. free (lower_bound);
  3909. conservative--;
  3910. return omega_false;
  3911. }
  3912. free (rS);
  3913. free (iS);
  3914. }
  3915. return omega_unknown;
  3916. } while (eliminate_again);
  3917. } while (1);
  3918. }
  3919. /* Because the omega solver is recursive, this counter limits the
  3920. recursion depth. */
  3921. static int omega_solve_depth = 0;
  3922. /* Return omega_true when the problem PB has a solution following the
  3923. DESIRED_RES. */
  3924. enum omega_result
  3925. omega_solve_problem (omega_pb pb, enum omega_result desired_res)
  3926. {
  3927. enum omega_result result;
  3928. gcc_assert (pb->num_vars >= pb->safe_vars);
  3929. omega_solve_depth++;
  3930. if (desired_res != omega_simplify)
  3931. pb->safe_vars = 0;
  3932. if (omega_solve_depth > 50)
  3933. {
  3934. if (dump_file && (dump_flags & TDF_DETAILS))
  3935. {
  3936. fprintf (dump_file,
  3937. "Solve depth = %d, in_approximate_mode = %d, aborting\n",
  3938. omega_solve_depth, in_approximate_mode);
  3939. omega_print_problem (dump_file, pb);
  3940. }
  3941. gcc_assert (0);
  3942. }
  3943. if (omega_solve_eq (pb, desired_res) == omega_false)
  3944. {
  3945. omega_solve_depth--;
  3946. return omega_false;
  3947. }
  3948. if (in_approximate_mode && !pb->num_geqs)
  3949. {
  3950. result = omega_true;
  3951. pb->num_vars = pb->safe_vars;
  3952. omega_problem_reduced (pb);
  3953. }
  3954. else
  3955. result = omega_solve_geq (pb, desired_res);
  3956. omega_solve_depth--;
  3957. if (!omega_reduce_with_subs)
  3958. {
  3959. resurrect_subs (pb);
  3960. gcc_assert (please_no_equalities_in_simplified_problems
  3961. || !result || pb->num_subs == 0);
  3962. }
  3963. return result;
  3964. }
  3965. /* Return true if red equations constrain the set of possible solutions.
  3966. We assume that there are solutions to the black equations by
  3967. themselves, so if there is no solution to the combined problem, we
  3968. return true. */
  3969. bool
  3970. omega_problem_has_red_equations (omega_pb pb)
  3971. {
  3972. bool result;
  3973. int e;
  3974. int i;
  3975. if (dump_file && (dump_flags & TDF_DETAILS))
  3976. {
  3977. fprintf (dump_file, "Checking for red equations:\n");
  3978. omega_print_problem (dump_file, pb);
  3979. }
  3980. please_no_equalities_in_simplified_problems++;
  3981. may_be_red++;
  3982. if (omega_single_result)
  3983. return_single_result++;
  3984. create_color = true;
  3985. result = (omega_simplify_problem (pb) == omega_false);
  3986. if (omega_single_result)
  3987. return_single_result--;
  3988. may_be_red--;
  3989. please_no_equalities_in_simplified_problems--;
  3990. if (result)
  3991. {
  3992. if (dump_file && (dump_flags & TDF_DETAILS))
  3993. fprintf (dump_file, "Gist is FALSE\n");
  3994. pb->num_subs = 0;
  3995. pb->num_geqs = 0;
  3996. pb->num_eqs = 1;
  3997. pb->eqs[0].color = omega_red;
  3998. for (i = pb->num_vars; i > 0; i--)
  3999. pb->eqs[0].coef[i] = 0;
  4000. pb->eqs[0].coef[0] = 1;
  4001. return true;
  4002. }
  4003. free_red_eliminations (pb);
  4004. gcc_assert (pb->num_eqs == 0);
  4005. for (e = pb->num_geqs - 1; e >= 0; e--)
  4006. if (pb->geqs[e].color == omega_red)
  4007. {
  4008. result = true;
  4009. break;
  4010. }
  4011. if (!result)
  4012. return false;
  4013. for (i = pb->safe_vars; i >= 1; i--)
  4014. {
  4015. int ub = 0;
  4016. int lb = 0;
  4017. for (e = pb->num_geqs - 1; e >= 0; e--)
  4018. {
  4019. if (pb->geqs[e].coef[i])
  4020. {
  4021. if (pb->geqs[e].coef[i] > 0)
  4022. lb |= (1 + (pb->geqs[e].color == omega_red ? 1 : 0));
  4023. else
  4024. ub |= (1 + (pb->geqs[e].color == omega_red ? 1 : 0));
  4025. }
  4026. }
  4027. if (ub == 2 || lb == 2)
  4028. {
  4029. if (dump_file && (dump_flags & TDF_DETAILS))
  4030. fprintf (dump_file, "checks for upper/lower bounds worked!\n");
  4031. if (!omega_reduce_with_subs)
  4032. {
  4033. resurrect_subs (pb);
  4034. gcc_assert (pb->num_subs == 0);
  4035. }
  4036. return true;
  4037. }
  4038. }
  4039. if (dump_file && (dump_flags & TDF_DETAILS))
  4040. fprintf (dump_file,
  4041. "*** Doing potentially expensive elimination tests "
  4042. "for red equations\n");
  4043. please_no_equalities_in_simplified_problems++;
  4044. omega_eliminate_red (pb, true);
  4045. please_no_equalities_in_simplified_problems--;
  4046. result = false;
  4047. gcc_assert (pb->num_eqs == 0);
  4048. for (e = pb->num_geqs - 1; e >= 0; e--)
  4049. if (pb->geqs[e].color == omega_red)
  4050. {
  4051. result = true;
  4052. break;
  4053. }
  4054. if (dump_file && (dump_flags & TDF_DETAILS))
  4055. {
  4056. if (!result)
  4057. fprintf (dump_file,
  4058. "******************** Redundant Red Equations eliminated!!\n");
  4059. else
  4060. fprintf (dump_file,
  4061. "******************** Red Equations remain\n");
  4062. omega_print_problem (dump_file, pb);
  4063. }
  4064. if (!omega_reduce_with_subs)
  4065. {
  4066. normalize_return_type r;
  4067. resurrect_subs (pb);
  4068. r = normalize_omega_problem (pb);
  4069. gcc_assert (r != normalize_false);
  4070. coalesce (pb);
  4071. cleanout_wildcards (pb);
  4072. gcc_assert (pb->num_subs == 0);
  4073. }
  4074. return result;
  4075. }
  4076. /* Calls omega_simplify_problem in approximate mode. */
  4077. enum omega_result
  4078. omega_simplify_approximate (omega_pb pb)
  4079. {
  4080. enum omega_result result;
  4081. if (dump_file && (dump_flags & TDF_DETAILS))
  4082. fprintf (dump_file, "(Entering approximate mode\n");
  4083. in_approximate_mode = true;
  4084. result = omega_simplify_problem (pb);
  4085. in_approximate_mode = false;
  4086. gcc_assert (pb->num_vars == pb->safe_vars);
  4087. if (!omega_reduce_with_subs)
  4088. gcc_assert (pb->num_subs == 0);
  4089. if (dump_file && (dump_flags & TDF_DETAILS))
  4090. fprintf (dump_file, "Leaving approximate mode)\n");
  4091. return result;
  4092. }
  4093. /* Simplifies problem PB by eliminating redundant constraints and
  4094. reducing the constraints system to a minimal form. Returns
  4095. omega_true when the problem was successfully reduced, omega_unknown
  4096. when the solver is unable to determine an answer. */
  4097. enum omega_result
  4098. omega_simplify_problem (omega_pb pb)
  4099. {
  4100. int i;
  4101. omega_found_reduction = omega_false;
  4102. if (!pb->variables_initialized)
  4103. omega_initialize_variables (pb);
  4104. if (next_key * 3 > MAX_KEYS)
  4105. {
  4106. int e;
  4107. hash_version++;
  4108. next_key = OMEGA_MAX_VARS + 1;
  4109. for (e = pb->num_geqs - 1; e >= 0; e--)
  4110. pb->geqs[e].touched = 1;
  4111. for (i = 0; i < HASH_TABLE_SIZE; i++)
  4112. hash_master[i].touched = -1;
  4113. pb->hash_version = hash_version;
  4114. }
  4115. else if (pb->hash_version != hash_version)
  4116. {
  4117. int e;
  4118. for (e = pb->num_geqs - 1; e >= 0; e--)
  4119. pb->geqs[e].touched = 1;
  4120. pb->hash_version = hash_version;
  4121. }
  4122. if (pb->num_vars > pb->num_eqs + 3 * pb->safe_vars)
  4123. omega_free_eliminations (pb, pb->safe_vars);
  4124. if (!may_be_red && pb->num_subs == 0 && pb->safe_vars == 0)
  4125. {
  4126. omega_found_reduction = omega_solve_problem (pb, omega_unknown);
  4127. if (omega_found_reduction != omega_false
  4128. && !return_single_result)
  4129. {
  4130. pb->num_geqs = 0;
  4131. pb->num_eqs = 0;
  4132. (*omega_when_reduced) (pb);
  4133. }
  4134. return omega_found_reduction;
  4135. }
  4136. omega_solve_problem (pb, omega_simplify);
  4137. if (omega_found_reduction != omega_false)
  4138. {
  4139. for (i = 1; omega_safe_var_p (pb, i); i++)
  4140. pb->forwarding_address[pb->var[i]] = i;
  4141. for (i = 0; i < pb->num_subs; i++)
  4142. pb->forwarding_address[pb->subs[i].key] = -i - 1;
  4143. }
  4144. if (!omega_reduce_with_subs)
  4145. gcc_assert (please_no_equalities_in_simplified_problems
  4146. || omega_found_reduction == omega_false
  4147. || pb->num_subs == 0);
  4148. return omega_found_reduction;
  4149. }
  4150. /* Make variable VAR unprotected: it then can be eliminated. */
  4151. void
  4152. omega_unprotect_variable (omega_pb pb, int var)
  4153. {
  4154. int e, idx;
  4155. idx = pb->forwarding_address[var];
  4156. if (idx < 0)
  4157. {
  4158. idx = -1 - idx;
  4159. pb->num_subs--;
  4160. if (idx < pb->num_subs)
  4161. {
  4162. omega_copy_eqn (&pb->subs[idx], &pb->subs[pb->num_subs],
  4163. pb->num_vars);
  4164. pb->forwarding_address[pb->subs[idx].key] = -idx - 1;
  4165. }
  4166. }
  4167. else
  4168. {
  4169. int *bring_to_life = XNEWVEC (int, OMEGA_MAX_VARS);
  4170. int e2;
  4171. for (e = pb->num_subs - 1; e >= 0; e--)
  4172. bring_to_life[e] = (pb->subs[e].coef[idx] != 0);
  4173. for (e2 = pb->num_subs - 1; e2 >= 0; e2--)
  4174. if (bring_to_life[e2])
  4175. {
  4176. pb->num_vars++;
  4177. pb->safe_vars++;
  4178. if (pb->safe_vars < pb->num_vars)
  4179. {
  4180. for (e = pb->num_geqs - 1; e >= 0; e--)
  4181. {
  4182. pb->geqs[e].coef[pb->num_vars] =
  4183. pb->geqs[e].coef[pb->safe_vars];
  4184. pb->geqs[e].coef[pb->safe_vars] = 0;
  4185. }
  4186. for (e = pb->num_eqs - 1; e >= 0; e--)
  4187. {
  4188. pb->eqs[e].coef[pb->num_vars] =
  4189. pb->eqs[e].coef[pb->safe_vars];
  4190. pb->eqs[e].coef[pb->safe_vars] = 0;
  4191. }
  4192. for (e = pb->num_subs - 1; e >= 0; e--)
  4193. {
  4194. pb->subs[e].coef[pb->num_vars] =
  4195. pb->subs[e].coef[pb->safe_vars];
  4196. pb->subs[e].coef[pb->safe_vars] = 0;
  4197. }
  4198. pb->var[pb->num_vars] = pb->var[pb->safe_vars];
  4199. pb->forwarding_address[pb->var[pb->num_vars]] =
  4200. pb->num_vars;
  4201. }
  4202. else
  4203. {
  4204. for (e = pb->num_geqs - 1; e >= 0; e--)
  4205. pb->geqs[e].coef[pb->safe_vars] = 0;
  4206. for (e = pb->num_eqs - 1; e >= 0; e--)
  4207. pb->eqs[e].coef[pb->safe_vars] = 0;
  4208. for (e = pb->num_subs - 1; e >= 0; e--)
  4209. pb->subs[e].coef[pb->safe_vars] = 0;
  4210. }
  4211. pb->var[pb->safe_vars] = pb->subs[e2].key;
  4212. pb->forwarding_address[pb->subs[e2].key] = pb->safe_vars;
  4213. omega_copy_eqn (&(pb->eqs[pb->num_eqs]), &(pb->subs[e2]),
  4214. pb->num_vars);
  4215. pb->eqs[pb->num_eqs++].coef[pb->safe_vars] = -1;
  4216. gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
  4217. if (e2 < pb->num_subs - 1)
  4218. omega_copy_eqn (&(pb->subs[e2]), &(pb->subs[pb->num_subs - 1]),
  4219. pb->num_vars);
  4220. pb->num_subs--;
  4221. }
  4222. omega_unprotect_1 (pb, &idx, NULL);
  4223. free (bring_to_life);
  4224. }
  4225. chain_unprotect (pb);
  4226. }
  4227. /* Unprotects VAR and simplifies PB. */
  4228. enum omega_result
  4229. omega_constrain_variable_sign (omega_pb pb, enum omega_eqn_color color,
  4230. int var, int sign)
  4231. {
  4232. int n_vars = pb->num_vars;
  4233. int e, j;
  4234. int k = pb->forwarding_address[var];
  4235. if (k < 0)
  4236. {
  4237. k = -1 - k;
  4238. if (sign != 0)
  4239. {
  4240. e = pb->num_geqs++;
  4241. omega_copy_eqn (&pb->geqs[e], &pb->subs[k], pb->num_vars);
  4242. for (j = 0; j <= n_vars; j++)
  4243. pb->geqs[e].coef[j] *= sign;
  4244. pb->geqs[e].coef[0]--;
  4245. pb->geqs[e].touched = 1;
  4246. pb->geqs[e].color = color;
  4247. }
  4248. else
  4249. {
  4250. e = pb->num_eqs++;
  4251. gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
  4252. omega_copy_eqn (&pb->eqs[e], &pb->subs[k], pb->num_vars);
  4253. pb->eqs[e].color = color;
  4254. }
  4255. }
  4256. else if (sign != 0)
  4257. {
  4258. e = pb->num_geqs++;
  4259. omega_init_eqn_zero (&pb->geqs[e], pb->num_vars);
  4260. pb->geqs[e].coef[k] = sign;
  4261. pb->geqs[e].coef[0] = -1;
  4262. pb->geqs[e].touched = 1;
  4263. pb->geqs[e].color = color;
  4264. }
  4265. else
  4266. {
  4267. e = pb->num_eqs++;
  4268. gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
  4269. omega_init_eqn_zero (&pb->eqs[e], pb->num_vars);
  4270. pb->eqs[e].coef[k] = 1;
  4271. pb->eqs[e].color = color;
  4272. }
  4273. omega_unprotect_variable (pb, var);
  4274. return omega_simplify_problem (pb);
  4275. }
  4276. /* Add an equation "VAR = VALUE" with COLOR to PB. */
  4277. void
  4278. omega_constrain_variable_value (omega_pb pb, enum omega_eqn_color color,
  4279. int var, int value)
  4280. {
  4281. int e;
  4282. int k = pb->forwarding_address[var];
  4283. if (k < 0)
  4284. {
  4285. k = -1 - k;
  4286. e = pb->num_eqs++;
  4287. gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
  4288. omega_copy_eqn (&pb->eqs[e], &pb->subs[k], pb->num_vars);
  4289. pb->eqs[e].coef[0] -= value;
  4290. }
  4291. else
  4292. {
  4293. e = pb->num_eqs++;
  4294. omega_init_eqn_zero (&pb->eqs[e], pb->num_vars);
  4295. pb->eqs[e].coef[k] = 1;
  4296. pb->eqs[e].coef[0] = -value;
  4297. }
  4298. pb->eqs[e].color = color;
  4299. }
  4300. /* Return false when the upper and lower bounds are not coupled.
  4301. Initialize the bounds LOWER_BOUND and UPPER_BOUND for the values of
  4302. variable I. */
  4303. bool
  4304. omega_query_variable (omega_pb pb, int i, int *lower_bound, int *upper_bound)
  4305. {
  4306. int n_vars = pb->num_vars;
  4307. int e, j;
  4308. bool is_simple;
  4309. bool coupled = false;
  4310. *lower_bound = neg_infinity;
  4311. *upper_bound = pos_infinity;
  4312. i = pb->forwarding_address[i];
  4313. if (i < 0)
  4314. {
  4315. i = -i - 1;
  4316. for (j = 1; j <= n_vars; j++)
  4317. if (pb->subs[i].coef[j] != 0)
  4318. return true;
  4319. *upper_bound = *lower_bound = pb->subs[i].coef[0];
  4320. return false;
  4321. }
  4322. for (e = pb->num_subs - 1; e >= 0; e--)
  4323. if (pb->subs[e].coef[i] != 0)
  4324. {
  4325. coupled = true;
  4326. break;
  4327. }
  4328. for (e = pb->num_eqs - 1; e >= 0; e--)
  4329. if (pb->eqs[e].coef[i] != 0)
  4330. {
  4331. is_simple = true;
  4332. for (j = 1; j <= n_vars; j++)
  4333. if (i != j && pb->eqs[e].coef[j] != 0)
  4334. {
  4335. is_simple = false;
  4336. coupled = true;
  4337. break;
  4338. }
  4339. if (!is_simple)
  4340. continue;
  4341. else
  4342. {
  4343. *lower_bound = *upper_bound =
  4344. -pb->eqs[e].coef[i] * pb->eqs[e].coef[0];
  4345. return false;
  4346. }
  4347. }
  4348. for (e = pb->num_geqs - 1; e >= 0; e--)
  4349. if (pb->geqs[e].coef[i] != 0)
  4350. {
  4351. if (pb->geqs[e].key == i)
  4352. *lower_bound = MAX (*lower_bound, -pb->geqs[e].coef[0]);
  4353. else if (pb->geqs[e].key == -i)
  4354. *upper_bound = MIN (*upper_bound, pb->geqs[e].coef[0]);
  4355. else
  4356. coupled = true;
  4357. }
  4358. return coupled;
  4359. }
  4360. /* Sets the lower bound L and upper bound U for the values of variable
  4361. I, and sets COULD_BE_ZERO to true if variable I might take value
  4362. zero. LOWER_BOUND and UPPER_BOUND are bounds on the values of
  4363. variable I. */
  4364. static void
  4365. query_coupled_variable (omega_pb pb, int i, int *l, int *u,
  4366. bool *could_be_zero, int lower_bound, int upper_bound)
  4367. {
  4368. int e, b1, b2;
  4369. eqn eqn;
  4370. int sign;
  4371. int v;
  4372. /* Preconditions. */
  4373. gcc_assert (abs (pb->forwarding_address[i]) == 1
  4374. && pb->num_vars + pb->num_subs == 2
  4375. && pb->num_eqs + pb->num_subs == 1);
  4376. /* Define variable I in terms of variable V. */
  4377. if (pb->forwarding_address[i] == -1)
  4378. {
  4379. eqn = &pb->subs[0];
  4380. sign = 1;
  4381. v = 1;
  4382. }
  4383. else
  4384. {
  4385. eqn = &pb->eqs[0];
  4386. sign = -eqn->coef[1];
  4387. v = 2;
  4388. }
  4389. for (e = pb->num_geqs - 1; e >= 0; e--)
  4390. if (pb->geqs[e].coef[v] != 0)
  4391. {
  4392. if (pb->geqs[e].coef[v] == 1)
  4393. lower_bound = MAX (lower_bound, -pb->geqs[e].coef[0]);
  4394. else
  4395. upper_bound = MIN (upper_bound, pb->geqs[e].coef[0]);
  4396. }
  4397. if (lower_bound > upper_bound)
  4398. {
  4399. *l = pos_infinity;
  4400. *u = neg_infinity;
  4401. *could_be_zero = 0;
  4402. return;
  4403. }
  4404. if (lower_bound == neg_infinity)
  4405. {
  4406. if (eqn->coef[v] > 0)
  4407. b1 = sign * neg_infinity;
  4408. else
  4409. b1 = -sign * neg_infinity;
  4410. }
  4411. else
  4412. b1 = sign * (eqn->coef[0] + eqn->coef[v] * lower_bound);
  4413. if (upper_bound == pos_infinity)
  4414. {
  4415. if (eqn->coef[v] > 0)
  4416. b2 = sign * pos_infinity;
  4417. else
  4418. b2 = -sign * pos_infinity;
  4419. }
  4420. else
  4421. b2 = sign * (eqn->coef[0] + eqn->coef[v] * upper_bound);
  4422. *l = MAX (*l, b1 <= b2 ? b1 : b2);
  4423. *u = MIN (*u, b1 <= b2 ? b2 : b1);
  4424. *could_be_zero = (*l <= 0 && 0 <= *u
  4425. && int_mod (eqn->coef[0], abs (eqn->coef[v])) == 0);
  4426. }
  4427. /* Return false when a lower bound L and an upper bound U for variable
  4428. I in problem PB have been initialized. */
  4429. bool
  4430. omega_query_variable_bounds (omega_pb pb, int i, int *l, int *u)
  4431. {
  4432. *l = neg_infinity;
  4433. *u = pos_infinity;
  4434. if (!omega_query_variable (pb, i, l, u)
  4435. || (pb->num_vars == 1 && pb->forwarding_address[i] == 1))
  4436. return false;
  4437. if (abs (pb->forwarding_address[i]) == 1
  4438. && pb->num_vars + pb->num_subs == 2
  4439. && pb->num_eqs + pb->num_subs == 1)
  4440. {
  4441. bool could_be_zero;
  4442. query_coupled_variable (pb, i, l, u, &could_be_zero, neg_infinity,
  4443. pos_infinity);
  4444. return false;
  4445. }
  4446. return true;
  4447. }
  4448. /* For problem PB, return an integer that represents the classic data
  4449. dependence direction in function of the DD_LT, DD_EQ and DD_GT bit
  4450. masks that are added to the result. When DIST_KNOWN is true, DIST
  4451. is set to the classic data dependence distance. LOWER_BOUND and
  4452. UPPER_BOUND are bounds on the value of variable I, for example, it
  4453. is possible to narrow the iteration domain with safe approximations
  4454. of loop counts, and thus discard some data dependences that cannot
  4455. occur. */
  4456. int
  4457. omega_query_variable_signs (omega_pb pb, int i, int dd_lt,
  4458. int dd_eq, int dd_gt, int lower_bound,
  4459. int upper_bound, bool *dist_known, int *dist)
  4460. {
  4461. int result;
  4462. int l, u;
  4463. bool could_be_zero;
  4464. l = neg_infinity;
  4465. u = pos_infinity;
  4466. omega_query_variable (pb, i, &l, &u);
  4467. query_coupled_variable (pb, i, &l, &u, &could_be_zero, lower_bound,
  4468. upper_bound);
  4469. result = 0;
  4470. if (l < 0)
  4471. result |= dd_gt;
  4472. if (u > 0)
  4473. result |= dd_lt;
  4474. if (could_be_zero)
  4475. result |= dd_eq;
  4476. if (l == u)
  4477. {
  4478. *dist_known = true;
  4479. *dist = l;
  4480. }
  4481. else
  4482. *dist_known = false;
  4483. return result;
  4484. }
  4485. /* Initialize PB as an Omega problem with NVARS variables and NPROT
  4486. safe variables. Safe variables are not eliminated during the
  4487. Fourier-Motzkin elimination. Safe variables are all those
  4488. variables that are placed at the beginning of the array of
  4489. variables: P->var[0, ..., NPROT - 1]. */
  4490. omega_pb
  4491. omega_alloc_problem (int nvars, int nprot)
  4492. {
  4493. omega_pb pb;
  4494. gcc_assert (nvars <= OMEGA_MAX_VARS);
  4495. omega_initialize ();
  4496. /* Allocate and initialize PB. */
  4497. pb = XCNEW (struct omega_pb_d);
  4498. pb->var = XCNEWVEC (int, OMEGA_MAX_VARS + 2);
  4499. pb->forwarding_address = XCNEWVEC (int, OMEGA_MAX_VARS + 2);
  4500. pb->geqs = omega_alloc_eqns (0, OMEGA_MAX_GEQS);
  4501. pb->eqs = omega_alloc_eqns (0, OMEGA_MAX_EQS);
  4502. pb->subs = omega_alloc_eqns (0, OMEGA_MAX_VARS + 1);
  4503. pb->hash_version = hash_version;
  4504. pb->num_vars = nvars;
  4505. pb->safe_vars = nprot;
  4506. pb->variables_initialized = false;
  4507. pb->variables_freed = false;
  4508. pb->num_eqs = 0;
  4509. pb->num_geqs = 0;
  4510. pb->num_subs = 0;
  4511. return pb;
  4512. }
  4513. /* Keeps the state of the initialization. */
  4514. static bool omega_initialized = false;
  4515. /* Initialization of the Omega solver. */
  4516. void
  4517. omega_initialize (void)
  4518. {
  4519. int i;
  4520. if (omega_initialized)
  4521. return;
  4522. next_wild_card = 0;
  4523. next_key = OMEGA_MAX_VARS + 1;
  4524. packing = XCNEWVEC (int, OMEGA_MAX_VARS);
  4525. fast_lookup = XCNEWVEC (int, MAX_KEYS * 2);
  4526. fast_lookup_red = XCNEWVEC (int, MAX_KEYS * 2);
  4527. hash_master = omega_alloc_eqns (0, HASH_TABLE_SIZE);
  4528. for (i = 0; i < HASH_TABLE_SIZE; i++)
  4529. hash_master[i].touched = -1;
  4530. sprintf (wild_name[0], "1");
  4531. sprintf (wild_name[1], "a");
  4532. sprintf (wild_name[2], "b");
  4533. sprintf (wild_name[3], "c");
  4534. sprintf (wild_name[4], "d");
  4535. sprintf (wild_name[5], "e");
  4536. sprintf (wild_name[6], "f");
  4537. sprintf (wild_name[7], "g");
  4538. sprintf (wild_name[8], "h");
  4539. sprintf (wild_name[9], "i");
  4540. sprintf (wild_name[10], "j");
  4541. sprintf (wild_name[11], "k");
  4542. sprintf (wild_name[12], "l");
  4543. sprintf (wild_name[13], "m");
  4544. sprintf (wild_name[14], "n");
  4545. sprintf (wild_name[15], "o");
  4546. sprintf (wild_name[16], "p");
  4547. sprintf (wild_name[17], "q");
  4548. sprintf (wild_name[18], "r");
  4549. sprintf (wild_name[19], "s");
  4550. sprintf (wild_name[20], "t");
  4551. sprintf (wild_name[40 - 1], "alpha");
  4552. sprintf (wild_name[40 - 2], "beta");
  4553. sprintf (wild_name[40 - 3], "gamma");
  4554. sprintf (wild_name[40 - 4], "delta");
  4555. sprintf (wild_name[40 - 5], "tau");
  4556. sprintf (wild_name[40 - 6], "sigma");
  4557. sprintf (wild_name[40 - 7], "chi");
  4558. sprintf (wild_name[40 - 8], "omega");
  4559. sprintf (wild_name[40 - 9], "pi");
  4560. sprintf (wild_name[40 - 10], "ni");
  4561. sprintf (wild_name[40 - 11], "Alpha");
  4562. sprintf (wild_name[40 - 12], "Beta");
  4563. sprintf (wild_name[40 - 13], "Gamma");
  4564. sprintf (wild_name[40 - 14], "Delta");
  4565. sprintf (wild_name[40 - 15], "Tau");
  4566. sprintf (wild_name[40 - 16], "Sigma");
  4567. sprintf (wild_name[40 - 17], "Chi");
  4568. sprintf (wild_name[40 - 18], "Omega");
  4569. sprintf (wild_name[40 - 19], "xxx");
  4570. omega_initialized = true;
  4571. }