123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568 |
- /* Source code for an implementation of the Omega test, an integer
- programming algorithm for dependence analysis, by William Pugh,
- appeared in Supercomputing '91 and CACM Aug 92.
- This code has no license restrictions, and is considered public
- domain.
- Changes copyright (C) 2005-2015 Free Software Foundation, Inc.
- Contributed by Sebastian Pop <sebastian.pop@inria.fr>
- This file is part of GCC.
- GCC is free software; you can redistribute it and/or modify it under
- the terms of the GNU General Public License as published by the Free
- Software Foundation; either version 3, or (at your option) any later
- version.
- GCC is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- for more details.
- You should have received a copy of the GNU General Public License
- along with GCC; see the file COPYING3. If not see
- <http://www.gnu.org/licenses/>. */
- /* For a detailed description, see "Constraint-Based Array Dependence
- Analysis" William Pugh, David Wonnacott, TOPLAS'98 and David
- Wonnacott's thesis:
- ftp://ftp.cs.umd.edu/pub/omega/davewThesis/davewThesis.ps.gz
- */
- #include "config.h"
- #include "system.h"
- #include "coretypes.h"
- #include "hash-set.h"
- #include "machmode.h"
- #include "vec.h"
- #include "double-int.h"
- #include "input.h"
- #include "alias.h"
- #include "symtab.h"
- #include "options.h"
- #include "wide-int.h"
- #include "inchash.h"
- #include "tree.h"
- #include "diagnostic-core.h"
- #include "dumpfile.h"
- #include "omega.h"
- /* When set to true, keep substitution variables. When set to false,
- resurrect substitution variables (convert substitutions back to EQs). */
- static bool omega_reduce_with_subs = true;
- /* When set to true, omega_simplify_problem checks for problem with no
- solutions, calling verify_omega_pb. */
- static bool omega_verify_simplification = false;
- /* When set to true, only produce a single simplified result. */
- static bool omega_single_result = false;
- /* Set return_single_result to 1 when omega_single_result is true. */
- static int return_single_result = 0;
- /* Hash table for equations generated by the solver. */
- #define HASH_TABLE_SIZE PARAM_VALUE (PARAM_OMEGA_HASH_TABLE_SIZE)
- #define MAX_KEYS PARAM_VALUE (PARAM_OMEGA_MAX_KEYS)
- static eqn hash_master;
- static int next_key;
- static int hash_version = 0;
- /* Set to true for making the solver enter in approximation mode. */
- static bool in_approximate_mode = false;
- /* When set to zero, the solver is allowed to add new equalities to
- the problem to be solved. */
- static int conservative = 0;
- /* Set to omega_true when the problem was successfully reduced, set to
- omega_unknown when the solver is unable to determine an answer. */
- static enum omega_result omega_found_reduction;
- /* Set to true when the solver is allowed to add omega_red equations. */
- static bool create_color = false;
- /* Set to nonzero when the problem to be solved can be reduced. */
- static int may_be_red = 0;
- /* When false, there should be no substitution equations in the
- simplified problem. */
- static int please_no_equalities_in_simplified_problems = 0;
- /* Variables names for pretty printing. */
- static char wild_name[200][40];
- /* Pointer to the void problem. */
- static omega_pb no_problem = (omega_pb) 0;
- /* Pointer to the problem to be solved. */
- static omega_pb original_problem = (omega_pb) 0;
- /* Return the integer A divided by B. */
- static inline int
- int_div (int a, int b)
- {
- if (a > 0)
- return a/b;
- else
- return -((-a + b - 1)/b);
- }
- /* Return the integer A modulo B. */
- static inline int
- int_mod (int a, int b)
- {
- return a - b * int_div (a, b);
- }
- /* Test whether equation E is red. */
- static inline bool
- omega_eqn_is_red (eqn e, int desired_res)
- {
- return (desired_res == omega_simplify && e->color == omega_red);
- }
- /* Return a string for VARIABLE. */
- static inline char *
- omega_var_to_str (int variable)
- {
- if (0 <= variable && variable <= 20)
- return wild_name[variable];
- if (-20 < variable && variable < 0)
- return wild_name[40 + variable];
- /* Collapse all the entries that would have overflowed. */
- return wild_name[21];
- }
- /* Return a string for variable I in problem PB. */
- static inline char *
- omega_variable_to_str (omega_pb pb, int i)
- {
- return omega_var_to_str (pb->var[i]);
- }
- /* Do nothing function: used for default initializations. */
- void
- omega_no_procedure (omega_pb pb ATTRIBUTE_UNUSED)
- {
- }
- void (*omega_when_reduced) (omega_pb) = omega_no_procedure;
- /* Print to FILE from PB equation E with all its coefficients
- multiplied by C. */
- static void
- omega_print_term (FILE *file, omega_pb pb, eqn e, int c)
- {
- int i;
- bool first = true;
- int n = pb->num_vars;
- int went_first = -1;
- for (i = 1; i <= n; i++)
- if (c * e->coef[i] > 0)
- {
- first = false;
- went_first = i;
- if (c * e->coef[i] == 1)
- fprintf (file, "%s", omega_variable_to_str (pb, i));
- else
- fprintf (file, "%d * %s", c * e->coef[i],
- omega_variable_to_str (pb, i));
- break;
- }
- for (i = 1; i <= n; i++)
- if (i != went_first && c * e->coef[i] != 0)
- {
- if (!first && c * e->coef[i] > 0)
- fprintf (file, " + ");
- first = false;
- if (c * e->coef[i] == 1)
- fprintf (file, "%s", omega_variable_to_str (pb, i));
- else if (c * e->coef[i] == -1)
- fprintf (file, " - %s", omega_variable_to_str (pb, i));
- else
- fprintf (file, "%d * %s", c * e->coef[i],
- omega_variable_to_str (pb, i));
- }
- if (!first && c * e->coef[0] > 0)
- fprintf (file, " + ");
- if (first || c * e->coef[0] != 0)
- fprintf (file, "%d", c * e->coef[0]);
- }
- /* Print to FILE the equation E of problem PB. */
- void
- omega_print_eqn (FILE *file, omega_pb pb, eqn e, bool test, int extra)
- {
- int i;
- int n = pb->num_vars + extra;
- bool is_lt = test && e->coef[0] == -1;
- bool first;
- if (test)
- {
- if (e->touched)
- fprintf (file, "!");
- else if (e->key != 0)
- fprintf (file, "%d: ", e->key);
- }
- if (e->color == omega_red)
- fprintf (file, "[");
- first = true;
- for (i = is_lt ? 1 : 0; i <= n; i++)
- if (e->coef[i] < 0)
- {
- if (!first)
- fprintf (file, " + ");
- else
- first = false;
- if (i == 0)
- fprintf (file, "%d", -e->coef[i]);
- else if (e->coef[i] == -1)
- fprintf (file, "%s", omega_variable_to_str (pb, i));
- else
- fprintf (file, "%d * %s", -e->coef[i],
- omega_variable_to_str (pb, i));
- }
- if (first)
- {
- if (is_lt)
- {
- fprintf (file, "1");
- is_lt = false;
- }
- else
- fprintf (file, "0");
- }
- if (test == 0)
- fprintf (file, " = ");
- else if (is_lt)
- fprintf (file, " < ");
- else
- fprintf (file, " <= ");
- first = true;
- for (i = 0; i <= n; i++)
- if (e->coef[i] > 0)
- {
- if (!first)
- fprintf (file, " + ");
- else
- first = false;
- if (i == 0)
- fprintf (file, "%d", e->coef[i]);
- else if (e->coef[i] == 1)
- fprintf (file, "%s", omega_variable_to_str (pb, i));
- else
- fprintf (file, "%d * %s", e->coef[i],
- omega_variable_to_str (pb, i));
- }
- if (first)
- fprintf (file, "0");
- if (e->color == omega_red)
- fprintf (file, "]");
- }
- /* Print to FILE all the variables of problem PB. */
- static void
- omega_print_vars (FILE *file, omega_pb pb)
- {
- int i;
- fprintf (file, "variables = ");
- if (pb->safe_vars > 0)
- fprintf (file, "protected (");
- for (i = 1; i <= pb->num_vars; i++)
- {
- fprintf (file, "%s", omega_variable_to_str (pb, i));
- if (i == pb->safe_vars)
- fprintf (file, ")");
- if (i < pb->num_vars)
- fprintf (file, ", ");
- }
- fprintf (file, "\n");
- }
- /* Dump problem PB. */
- DEBUG_FUNCTION void
- debug (omega_pb_d &ref)
- {
- omega_print_problem (stderr, &ref);
- }
- DEBUG_FUNCTION void
- debug (omega_pb_d *ptr)
- {
- if (ptr)
- debug (*ptr);
- else
- fprintf (stderr, "<nil>\n");
- }
- /* Debug problem PB. */
- DEBUG_FUNCTION void
- debug_omega_problem (omega_pb pb)
- {
- omega_print_problem (stderr, pb);
- }
- /* Print to FILE problem PB. */
- void
- omega_print_problem (FILE *file, omega_pb pb)
- {
- int e;
- if (!pb->variables_initialized)
- omega_initialize_variables (pb);
- omega_print_vars (file, pb);
- for (e = 0; e < pb->num_eqs; e++)
- {
- omega_print_eq (file, pb, &pb->eqs[e]);
- fprintf (file, "\n");
- }
- fprintf (file, "Done with EQ\n");
- for (e = 0; e < pb->num_geqs; e++)
- {
- omega_print_geq (file, pb, &pb->geqs[e]);
- fprintf (file, "\n");
- }
- fprintf (file, "Done with GEQ\n");
- for (e = 0; e < pb->num_subs; e++)
- {
- eqn eq = &pb->subs[e];
- if (eq->color == omega_red)
- fprintf (file, "[");
- if (eq->key > 0)
- fprintf (file, "%s := ", omega_var_to_str (eq->key));
- else
- fprintf (file, "#%d := ", eq->key);
- omega_print_term (file, pb, eq, 1);
- if (eq->color == omega_red)
- fprintf (file, "]");
- fprintf (file, "\n");
- }
- }
- /* Return the number of equations in PB tagged omega_red. */
- int
- omega_count_red_equations (omega_pb pb)
- {
- int e, i;
- int result = 0;
- for (e = 0; e < pb->num_eqs; e++)
- if (pb->eqs[e].color == omega_red)
- {
- for (i = pb->num_vars; i > 0; i--)
- if (pb->geqs[e].coef[i])
- break;
- if (i == 0 && pb->geqs[e].coef[0] == 1)
- return 0;
- else
- result += 2;
- }
- for (e = 0; e < pb->num_geqs; e++)
- if (pb->geqs[e].color == omega_red)
- result += 1;
- for (e = 0; e < pb->num_subs; e++)
- if (pb->subs[e].color == omega_red)
- result += 2;
- return result;
- }
- /* Print to FILE all the equations in PB that are tagged omega_red. */
- void
- omega_print_red_equations (FILE *file, omega_pb pb)
- {
- int e;
- if (!pb->variables_initialized)
- omega_initialize_variables (pb);
- omega_print_vars (file, pb);
- for (e = 0; e < pb->num_eqs; e++)
- if (pb->eqs[e].color == omega_red)
- {
- omega_print_eq (file, pb, &pb->eqs[e]);
- fprintf (file, "\n");
- }
- for (e = 0; e < pb->num_geqs; e++)
- if (pb->geqs[e].color == omega_red)
- {
- omega_print_geq (file, pb, &pb->geqs[e]);
- fprintf (file, "\n");
- }
- for (e = 0; e < pb->num_subs; e++)
- if (pb->subs[e].color == omega_red)
- {
- eqn eq = &pb->subs[e];
- fprintf (file, "[");
- if (eq->key > 0)
- fprintf (file, "%s := ", omega_var_to_str (eq->key));
- else
- fprintf (file, "#%d := ", eq->key);
- omega_print_term (file, pb, eq, 1);
- fprintf (file, "]\n");
- }
- }
- /* Pretty print PB to FILE. */
- void
- omega_pretty_print_problem (FILE *file, omega_pb pb)
- {
- int e, v, v1, v2, v3, t;
- bool *live = XNEWVEC (bool, OMEGA_MAX_GEQS);
- int stuffPrinted = 0;
- bool change;
- typedef enum {
- none, le, lt
- } partial_order_type;
- partial_order_type **po = XNEWVEC (partial_order_type *,
- OMEGA_MAX_VARS * OMEGA_MAX_VARS);
- int **po_eq = XNEWVEC (int *, OMEGA_MAX_VARS * OMEGA_MAX_VARS);
- int *last_links = XNEWVEC (int, OMEGA_MAX_VARS);
- int *first_links = XNEWVEC (int, OMEGA_MAX_VARS);
- int *chain_length = XNEWVEC (int, OMEGA_MAX_VARS);
- int *chain = XNEWVEC (int, OMEGA_MAX_VARS);
- int i, m;
- bool multiprint;
- if (!pb->variables_initialized)
- omega_initialize_variables (pb);
- if (pb->num_vars > 0)
- {
- omega_eliminate_redundant (pb, false);
- for (e = 0; e < pb->num_eqs; e++)
- {
- if (stuffPrinted)
- fprintf (file, "; ");
- stuffPrinted = 1;
- omega_print_eq (file, pb, &pb->eqs[e]);
- }
- for (e = 0; e < pb->num_geqs; e++)
- live[e] = true;
- while (1)
- {
- for (v = 1; v <= pb->num_vars; v++)
- {
- last_links[v] = first_links[v] = 0;
- chain_length[v] = 0;
- for (v2 = 1; v2 <= pb->num_vars; v2++)
- po[v][v2] = none;
- }
- for (e = 0; e < pb->num_geqs; e++)
- if (live[e])
- {
- for (v = 1; v <= pb->num_vars; v++)
- if (pb->geqs[e].coef[v] == 1)
- first_links[v]++;
- else if (pb->geqs[e].coef[v] == -1)
- last_links[v]++;
- v1 = pb->num_vars;
- while (v1 > 0 && pb->geqs[e].coef[v1] == 0)
- v1--;
- v2 = v1 - 1;
- while (v2 > 0 && pb->geqs[e].coef[v2] == 0)
- v2--;
- v3 = v2 - 1;
- while (v3 > 0 && pb->geqs[e].coef[v3] == 0)
- v3--;
- if (pb->geqs[e].coef[0] > 0 || pb->geqs[e].coef[0] < -1
- || v2 <= 0 || v3 > 0
- || pb->geqs[e].coef[v1] * pb->geqs[e].coef[v2] != -1)
- {
- /* Not a partial order relation. */
- }
- else
- {
- if (pb->geqs[e].coef[v1] == 1)
- {
- v3 = v2;
- v2 = v1;
- v1 = v3;
- }
- /* Relation is v1 <= v2 or v1 < v2. */
- po[v1][v2] = ((pb->geqs[e].coef[0] == 0) ? le : lt);
- po_eq[v1][v2] = e;
- }
- }
- for (v = 1; v <= pb->num_vars; v++)
- chain_length[v] = last_links[v];
- /* Just in case pb->num_vars <= 0. */
- change = false;
- for (t = 0; t < pb->num_vars; t++)
- {
- change = false;
- for (v1 = 1; v1 <= pb->num_vars; v1++)
- for (v2 = 1; v2 <= pb->num_vars; v2++)
- if (po[v1][v2] != none &&
- chain_length[v1] <= chain_length[v2])
- {
- chain_length[v1] = chain_length[v2] + 1;
- change = true;
- }
- }
- /* Caught in cycle. */
- gcc_assert (!change);
- for (v1 = 1; v1 <= pb->num_vars; v1++)
- if (chain_length[v1] == 0)
- first_links[v1] = 0;
- v = 1;
- for (v1 = 2; v1 <= pb->num_vars; v1++)
- if (chain_length[v1] + first_links[v1] >
- chain_length[v] + first_links[v])
- v = v1;
- if (chain_length[v] + first_links[v] == 0)
- break;
- if (stuffPrinted)
- fprintf (file, "; ");
- stuffPrinted = 1;
- /* Chain starts at v. */
- {
- int tmp;
- bool first = true;
- for (e = 0; e < pb->num_geqs; e++)
- if (live[e] && pb->geqs[e].coef[v] == 1)
- {
- if (!first)
- fprintf (file, ", ");
- tmp = pb->geqs[e].coef[v];
- pb->geqs[e].coef[v] = 0;
- omega_print_term (file, pb, &pb->geqs[e], -1);
- pb->geqs[e].coef[v] = tmp;
- live[e] = false;
- first = false;
- }
- if (!first)
- fprintf (file, " <= ");
- }
- /* Find chain. */
- chain[0] = v;
- m = 1;
- while (1)
- {
- /* Print chain. */
- for (v2 = 1; v2 <= pb->num_vars; v2++)
- if (po[v][v2] && chain_length[v] == 1 + chain_length[v2])
- break;
- if (v2 > pb->num_vars)
- break;
- chain[m++] = v2;
- v = v2;
- }
- fprintf (file, "%s", omega_variable_to_str (pb, chain[0]));
- for (multiprint = false, i = 1; i < m; i++)
- {
- v = chain[i - 1];
- v2 = chain[i];
- if (po[v][v2] == le)
- fprintf (file, " <= ");
- else
- fprintf (file, " < ");
- fprintf (file, "%s", omega_variable_to_str (pb, v2));
- live[po_eq[v][v2]] = false;
- if (!multiprint && i < m - 1)
- for (v3 = 1; v3 <= pb->num_vars; v3++)
- {
- if (v == v3 || v2 == v3
- || po[v][v2] != po[v][v3]
- || po[v2][chain[i + 1]] != po[v3][chain[i + 1]])
- continue;
- fprintf (file, ",%s", omega_variable_to_str (pb, v3));
- live[po_eq[v][v3]] = false;
- live[po_eq[v3][chain[i + 1]]] = false;
- multiprint = true;
- }
- else
- multiprint = false;
- }
- v = chain[m - 1];
- /* Print last_links. */
- {
- int tmp;
- bool first = true;
- for (e = 0; e < pb->num_geqs; e++)
- if (live[e] && pb->geqs[e].coef[v] == -1)
- {
- if (!first)
- fprintf (file, ", ");
- else
- fprintf (file, " <= ");
- tmp = pb->geqs[e].coef[v];
- pb->geqs[e].coef[v] = 0;
- omega_print_term (file, pb, &pb->geqs[e], 1);
- pb->geqs[e].coef[v] = tmp;
- live[e] = false;
- first = false;
- }
- }
- }
- for (e = 0; e < pb->num_geqs; e++)
- if (live[e])
- {
- if (stuffPrinted)
- fprintf (file, "; ");
- stuffPrinted = 1;
- omega_print_geq (file, pb, &pb->geqs[e]);
- }
- for (e = 0; e < pb->num_subs; e++)
- {
- eqn eq = &pb->subs[e];
- if (stuffPrinted)
- fprintf (file, "; ");
- stuffPrinted = 1;
- if (eq->key > 0)
- fprintf (file, "%s := ", omega_var_to_str (eq->key));
- else
- fprintf (file, "#%d := ", eq->key);
- omega_print_term (file, pb, eq, 1);
- }
- }
- free (live);
- free (po);
- free (po_eq);
- free (last_links);
- free (first_links);
- free (chain_length);
- free (chain);
- }
- /* Assign to variable I in PB the next wildcard name. The name of a
- wildcard is a negative number. */
- static int next_wild_card = 0;
- static void
- omega_name_wild_card (omega_pb pb, int i)
- {
- --next_wild_card;
- if (next_wild_card < -PARAM_VALUE (PARAM_OMEGA_MAX_WILD_CARDS))
- next_wild_card = -1;
- pb->var[i] = next_wild_card;
- }
- /* Return the index of the last protected (or safe) variable in PB,
- after having added a new wildcard variable. */
- static int
- omega_add_new_wild_card (omega_pb pb)
- {
- int e;
- int i = ++pb->safe_vars;
- pb->num_vars++;
- /* Make a free place in the protected (safe) variables, by moving
- the non protected variable pointed by "I" at the end, ie. at
- offset pb->num_vars. */
- if (pb->num_vars != i)
- {
- /* Move "I" for all the inequalities. */
- for (e = pb->num_geqs - 1; e >= 0; e--)
- {
- if (pb->geqs[e].coef[i])
- pb->geqs[e].touched = 1;
- pb->geqs[e].coef[pb->num_vars] = pb->geqs[e].coef[i];
- }
- /* Move "I" for all the equalities. */
- for (e = pb->num_eqs - 1; e >= 0; e--)
- pb->eqs[e].coef[pb->num_vars] = pb->eqs[e].coef[i];
- /* Move "I" for all the substitutions. */
- for (e = pb->num_subs - 1; e >= 0; e--)
- pb->subs[e].coef[pb->num_vars] = pb->subs[e].coef[i];
- /* Move the identifier. */
- pb->var[pb->num_vars] = pb->var[i];
- }
- /* Initialize at zero all the coefficients */
- for (e = pb->num_geqs - 1; e >= 0; e--)
- pb->geqs[e].coef[i] = 0;
- for (e = pb->num_eqs - 1; e >= 0; e--)
- pb->eqs[e].coef[i] = 0;
- for (e = pb->num_subs - 1; e >= 0; e--)
- pb->subs[e].coef[i] = 0;
- /* And give it a name. */
- omega_name_wild_card (pb, i);
- return i;
- }
- /* Delete inequality E from problem PB that has N_VARS variables. */
- static void
- omega_delete_geq (omega_pb pb, int e, int n_vars)
- {
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file, "Deleting %d (last:%d): ", e, pb->num_geqs - 1);
- omega_print_geq (dump_file, pb, &pb->geqs[e]);
- fprintf (dump_file, "\n");
- }
- if (e < pb->num_geqs - 1)
- omega_copy_eqn (&pb->geqs[e], &pb->geqs[pb->num_geqs - 1], n_vars);
- pb->num_geqs--;
- }
- /* Delete extra inequality E from problem PB that has N_VARS
- variables. */
- static void
- omega_delete_geq_extra (omega_pb pb, int e, int n_vars)
- {
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file, "Deleting %d: ",e);
- omega_print_geq_extra (dump_file, pb, &pb->geqs[e]);
- fprintf (dump_file, "\n");
- }
- if (e < pb->num_geqs - 1)
- omega_copy_eqn (&pb->geqs[e], &pb->geqs[pb->num_geqs - 1], n_vars);
- pb->num_geqs--;
- }
- /* Remove variable I from problem PB. */
- static void
- omega_delete_variable (omega_pb pb, int i)
- {
- int n_vars = pb->num_vars;
- int e;
- if (omega_safe_var_p (pb, i))
- {
- int j = pb->safe_vars;
- for (e = pb->num_geqs - 1; e >= 0; e--)
- {
- pb->geqs[e].touched = 1;
- pb->geqs[e].coef[i] = pb->geqs[e].coef[j];
- pb->geqs[e].coef[j] = pb->geqs[e].coef[n_vars];
- }
- for (e = pb->num_eqs - 1; e >= 0; e--)
- {
- pb->eqs[e].coef[i] = pb->eqs[e].coef[j];
- pb->eqs[e].coef[j] = pb->eqs[e].coef[n_vars];
- }
- for (e = pb->num_subs - 1; e >= 0; e--)
- {
- pb->subs[e].coef[i] = pb->subs[e].coef[j];
- pb->subs[e].coef[j] = pb->subs[e].coef[n_vars];
- }
- pb->var[i] = pb->var[j];
- pb->var[j] = pb->var[n_vars];
- }
- else if (i < n_vars)
- {
- for (e = pb->num_geqs - 1; e >= 0; e--)
- if (pb->geqs[e].coef[n_vars])
- {
- pb->geqs[e].coef[i] = pb->geqs[e].coef[n_vars];
- pb->geqs[e].touched = 1;
- }
- for (e = pb->num_eqs - 1; e >= 0; e--)
- pb->eqs[e].coef[i] = pb->eqs[e].coef[n_vars];
- for (e = pb->num_subs - 1; e >= 0; e--)
- pb->subs[e].coef[i] = pb->subs[e].coef[n_vars];
- pb->var[i] = pb->var[n_vars];
- }
- if (omega_safe_var_p (pb, i))
- pb->safe_vars--;
- pb->num_vars--;
- }
- /* Because the coefficients of an equation are sparse, PACKING records
- indices for non null coefficients. */
- static int *packing;
- /* Set up the coefficients of PACKING, following the coefficients of
- equation EQN that has NUM_VARS variables. */
- static inline int
- setup_packing (eqn eqn, int num_vars)
- {
- int k;
- int n = 0;
- for (k = num_vars; k >= 0; k--)
- if (eqn->coef[k])
- packing[n++] = k;
- return n;
- }
- /* Computes a linear combination of EQ and SUB at VAR with coefficient
- C, such that EQ->coef[VAR] is set to 0. TOP_VAR is the number of
- non null indices of SUB stored in PACKING. */
- static inline void
- omega_substitute_red_1 (eqn eq, eqn sub, int var, int c, bool *found_black,
- int top_var)
- {
- if (eq->coef[var] != 0)
- {
- if (eq->color == omega_black)
- *found_black = true;
- else
- {
- int j, k = eq->coef[var];
- eq->coef[var] = 0;
- for (j = top_var; j >= 0; j--)
- eq->coef[packing[j]] -= sub->coef[packing[j]] * k * c;
- }
- }
- }
- /* Substitute in PB variable VAR with "C * SUB". */
- static void
- omega_substitute_red (omega_pb pb, eqn sub, int var, int c, bool *found_black)
- {
- int e, top_var = setup_packing (sub, pb->num_vars);
- *found_black = false;
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- if (sub->color == omega_red)
- fprintf (dump_file, "[");
- fprintf (dump_file, "substituting using %s := ",
- omega_variable_to_str (pb, var));
- omega_print_term (dump_file, pb, sub, -c);
- if (sub->color == omega_red)
- fprintf (dump_file, "]");
- fprintf (dump_file, "\n");
- omega_print_vars (dump_file, pb);
- }
- for (e = pb->num_eqs - 1; e >= 0; e--)
- {
- eqn eqn = &(pb->eqs[e]);
- omega_substitute_red_1 (eqn, sub, var, c, found_black, top_var);
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- omega_print_eq (dump_file, pb, eqn);
- fprintf (dump_file, "\n");
- }
- }
- for (e = pb->num_geqs - 1; e >= 0; e--)
- {
- eqn eqn = &(pb->geqs[e]);
- omega_substitute_red_1 (eqn, sub, var, c, found_black, top_var);
- if (eqn->coef[var] && eqn->color == omega_red)
- eqn->touched = 1;
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- omega_print_geq (dump_file, pb, eqn);
- fprintf (dump_file, "\n");
- }
- }
- for (e = pb->num_subs - 1; e >= 0; e--)
- {
- eqn eqn = &(pb->subs[e]);
- omega_substitute_red_1 (eqn, sub, var, c, found_black, top_var);
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file, "%s := ", omega_var_to_str (eqn->key));
- omega_print_term (dump_file, pb, eqn, 1);
- fprintf (dump_file, "\n");
- }
- }
- if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file, "---\n\n");
- if (omega_safe_var_p (pb, var) && !omega_wildcard_p (pb, var))
- *found_black = true;
- }
- /* Substitute in PB variable VAR with "C * SUB". */
- static void
- omega_substitute (omega_pb pb, eqn sub, int var, int c)
- {
- int e, j, j0;
- int top_var = setup_packing (sub, pb->num_vars);
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file, "substituting using %s := ",
- omega_variable_to_str (pb, var));
- omega_print_term (dump_file, pb, sub, -c);
- fprintf (dump_file, "\n");
- omega_print_vars (dump_file, pb);
- }
- if (top_var < 0)
- {
- for (e = pb->num_eqs - 1; e >= 0; e--)
- pb->eqs[e].coef[var] = 0;
- for (e = pb->num_geqs - 1; e >= 0; e--)
- if (pb->geqs[e].coef[var] != 0)
- {
- pb->geqs[e].touched = 1;
- pb->geqs[e].coef[var] = 0;
- }
- for (e = pb->num_subs - 1; e >= 0; e--)
- pb->subs[e].coef[var] = 0;
- if (omega_safe_var_p (pb, var) && !omega_wildcard_p (pb, var))
- {
- int k;
- eqn eqn = &(pb->subs[pb->num_subs++]);
- for (k = pb->num_vars; k >= 0; k--)
- eqn->coef[k] = 0;
- eqn->key = pb->var[var];
- eqn->color = omega_black;
- }
- }
- else if (top_var == 0 && packing[0] == 0)
- {
- c = -sub->coef[0] * c;
- for (e = pb->num_eqs - 1; e >= 0; e--)
- {
- pb->eqs[e].coef[0] += pb->eqs[e].coef[var] * c;
- pb->eqs[e].coef[var] = 0;
- }
- for (e = pb->num_geqs - 1; e >= 0; e--)
- if (pb->geqs[e].coef[var] != 0)
- {
- pb->geqs[e].coef[0] += pb->geqs[e].coef[var] * c;
- pb->geqs[e].coef[var] = 0;
- pb->geqs[e].touched = 1;
- }
- for (e = pb->num_subs - 1; e >= 0; e--)
- {
- pb->subs[e].coef[0] += pb->subs[e].coef[var] * c;
- pb->subs[e].coef[var] = 0;
- }
- if (omega_safe_var_p (pb, var) && !omega_wildcard_p (pb, var))
- {
- int k;
- eqn eqn = &(pb->subs[pb->num_subs++]);
- for (k = pb->num_vars; k >= 1; k--)
- eqn->coef[k] = 0;
- eqn->coef[0] = c;
- eqn->key = pb->var[var];
- eqn->color = omega_black;
- }
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file, "---\n\n");
- omega_print_problem (dump_file, pb);
- fprintf (dump_file, "===\n\n");
- }
- }
- else
- {
- for (e = pb->num_eqs - 1; e >= 0; e--)
- {
- eqn eqn = &(pb->eqs[e]);
- int k = eqn->coef[var];
- if (k != 0)
- {
- k = c * k;
- eqn->coef[var] = 0;
- for (j = top_var; j >= 0; j--)
- {
- j0 = packing[j];
- eqn->coef[j0] -= sub->coef[j0] * k;
- }
- }
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- omega_print_eq (dump_file, pb, eqn);
- fprintf (dump_file, "\n");
- }
- }
- for (e = pb->num_geqs - 1; e >= 0; e--)
- {
- eqn eqn = &(pb->geqs[e]);
- int k = eqn->coef[var];
- if (k != 0)
- {
- k = c * k;
- eqn->touched = 1;
- eqn->coef[var] = 0;
- for (j = top_var; j >= 0; j--)
- {
- j0 = packing[j];
- eqn->coef[j0] -= sub->coef[j0] * k;
- }
- }
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- omega_print_geq (dump_file, pb, eqn);
- fprintf (dump_file, "\n");
- }
- }
- for (e = pb->num_subs - 1; e >= 0; e--)
- {
- eqn eqn = &(pb->subs[e]);
- int k = eqn->coef[var];
- if (k != 0)
- {
- k = c * k;
- eqn->coef[var] = 0;
- for (j = top_var; j >= 0; j--)
- {
- j0 = packing[j];
- eqn->coef[j0] -= sub->coef[j0] * k;
- }
- }
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file, "%s := ", omega_var_to_str (eqn->key));
- omega_print_term (dump_file, pb, eqn, 1);
- fprintf (dump_file, "\n");
- }
- }
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file, "---\n\n");
- omega_print_problem (dump_file, pb);
- fprintf (dump_file, "===\n\n");
- }
- if (omega_safe_var_p (pb, var) && !omega_wildcard_p (pb, var))
- {
- int k;
- eqn eqn = &(pb->subs[pb->num_subs++]);
- c = -c;
- for (k = pb->num_vars; k >= 0; k--)
- eqn->coef[k] = c * (sub->coef[k]);
- eqn->key = pb->var[var];
- eqn->color = sub->color;
- }
- }
- }
- /* Solve e = factor alpha for x_j and substitute. */
- static void
- omega_do_mod (omega_pb pb, int factor, int e, int j)
- {
- int k, i;
- eqn eq = omega_alloc_eqns (0, 1);
- int nfactor;
- bool kill_j = false;
- omega_copy_eqn (eq, &pb->eqs[e], pb->num_vars);
- for (k = pb->num_vars; k >= 0; k--)
- {
- eq->coef[k] = int_mod (eq->coef[k], factor);
- if (2 * eq->coef[k] >= factor)
- eq->coef[k] -= factor;
- }
- nfactor = eq->coef[j];
- if (omega_safe_var_p (pb, j) && !omega_wildcard_p (pb, j))
- {
- i = omega_add_new_wild_card (pb);
- eq->coef[pb->num_vars] = eq->coef[i];
- eq->coef[j] = 0;
- eq->coef[i] = -factor;
- kill_j = true;
- }
- else
- {
- eq->coef[j] = -factor;
- if (!omega_wildcard_p (pb, j))
- omega_name_wild_card (pb, j);
- }
- omega_substitute (pb, eq, j, nfactor);
- for (k = pb->num_vars; k >= 0; k--)
- pb->eqs[e].coef[k] = pb->eqs[e].coef[k] / factor;
- if (kill_j)
- omega_delete_variable (pb, j);
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file, "Mod-ing and normalizing produces:\n");
- omega_print_problem (dump_file, pb);
- }
- omega_free_eqns (eq, 1);
- }
- /* Multiplies by -1 inequality E. */
- void
- omega_negate_geq (omega_pb pb, int e)
- {
- int i;
- for (i = pb->num_vars; i >= 0; i--)
- pb->geqs[e].coef[i] *= -1;
- pb->geqs[e].coef[0]--;
- pb->geqs[e].touched = 1;
- }
- /* Returns OMEGA_TRUE when problem PB has a solution. */
- static enum omega_result
- verify_omega_pb (omega_pb pb)
- {
- enum omega_result result;
- int e;
- bool any_color = false;
- omega_pb tmp_problem = XNEW (struct omega_pb_d);
- omega_copy_problem (tmp_problem, pb);
- tmp_problem->safe_vars = 0;
- tmp_problem->num_subs = 0;
- for (e = pb->num_geqs - 1; e >= 0; e--)
- if (pb->geqs[e].color == omega_red)
- {
- any_color = true;
- break;
- }
- if (please_no_equalities_in_simplified_problems)
- any_color = true;
- if (any_color)
- original_problem = no_problem;
- else
- original_problem = pb;
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file, "verifying problem");
- if (any_color)
- fprintf (dump_file, " (color mode)");
- fprintf (dump_file, " :\n");
- omega_print_problem (dump_file, pb);
- }
- result = omega_solve_problem (tmp_problem, omega_unknown);
- original_problem = no_problem;
- free (tmp_problem);
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- if (result != omega_false)
- fprintf (dump_file, "verified problem\n");
- else
- fprintf (dump_file, "disproved problem\n");
- omega_print_problem (dump_file, pb);
- }
- return result;
- }
- /* Add a new equality to problem PB at last position E. */
- static void
- adding_equality_constraint (omega_pb pb, int e)
- {
- if (original_problem != no_problem
- && original_problem != pb
- && !conservative)
- {
- int i, j;
- int e2 = original_problem->num_eqs++;
- if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file,
- "adding equality constraint %d to outer problem\n", e2);
- omega_init_eqn_zero (&original_problem->eqs[e2],
- original_problem->num_vars);
- for (i = pb->num_vars; i >= 1; i--)
- {
- for (j = original_problem->num_vars; j >= 1; j--)
- if (original_problem->var[j] == pb->var[i])
- break;
- if (j <= 0)
- {
- if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file, "retracting\n");
- original_problem->num_eqs--;
- return;
- }
- original_problem->eqs[e2].coef[j] = pb->eqs[e].coef[i];
- }
- original_problem->eqs[e2].coef[0] = pb->eqs[e].coef[0];
- if (dump_file && (dump_flags & TDF_DETAILS))
- omega_print_problem (dump_file, original_problem);
- }
- }
- static int *fast_lookup;
- static int *fast_lookup_red;
- typedef enum {
- normalize_false,
- normalize_uncoupled,
- normalize_coupled
- } normalize_return_type;
- /* Normalizes PB by removing redundant constraints. Returns
- normalize_false when the constraints system has no solution,
- otherwise returns normalize_coupled or normalize_uncoupled. */
- static normalize_return_type
- normalize_omega_problem (omega_pb pb)
- {
- int e, i, j, k, n_vars;
- int coupled_subscripts = 0;
- n_vars = pb->num_vars;
- for (e = 0; e < pb->num_geqs; e++)
- {
- if (!pb->geqs[e].touched)
- {
- if (!single_var_geq (&pb->geqs[e], n_vars))
- coupled_subscripts = 1;
- }
- else
- {
- int g, top_var, i0, hashCode;
- int *p = &packing[0];
- for (k = 1; k <= n_vars; k++)
- if (pb->geqs[e].coef[k])
- *(p++) = k;
- top_var = (p - &packing[0]) - 1;
- if (top_var == -1)
- {
- if (pb->geqs[e].coef[0] < 0)
- {
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- omega_print_geq (dump_file, pb, &pb->geqs[e]);
- fprintf (dump_file, "\nequations have no solution \n");
- }
- return normalize_false;
- }
- omega_delete_geq (pb, e, n_vars);
- e--;
- continue;
- }
- else if (top_var == 0)
- {
- int singlevar = packing[0];
- g = pb->geqs[e].coef[singlevar];
- if (g > 0)
- {
- pb->geqs[e].coef[singlevar] = 1;
- pb->geqs[e].key = singlevar;
- }
- else
- {
- g = -g;
- pb->geqs[e].coef[singlevar] = -1;
- pb->geqs[e].key = -singlevar;
- }
- if (g > 1)
- pb->geqs[e].coef[0] = int_div (pb->geqs[e].coef[0], g);
- }
- else
- {
- int g2;
- int hash_key_multiplier = 31;
- coupled_subscripts = 1;
- i0 = top_var;
- i = packing[i0--];
- g = pb->geqs[e].coef[i];
- hashCode = g * (i + 3);
- if (g < 0)
- g = -g;
- for (; i0 >= 0; i0--)
- {
- int x;
- i = packing[i0];
- x = pb->geqs[e].coef[i];
- hashCode = hashCode * hash_key_multiplier * (i + 3) + x;
- if (x < 0)
- x = -x;
- if (x == 1)
- {
- g = 1;
- i0--;
- break;
- }
- else
- g = gcd (x, g);
- }
- for (; i0 >= 0; i0--)
- {
- int x;
- i = packing[i0];
- x = pb->geqs[e].coef[i];
- hashCode = hashCode * hash_key_multiplier * (i + 3) + x;
- }
- if (g > 1)
- {
- pb->geqs[e].coef[0] = int_div (pb->geqs[e].coef[0], g);
- i0 = top_var;
- i = packing[i0--];
- pb->geqs[e].coef[i] = pb->geqs[e].coef[i] / g;
- hashCode = pb->geqs[e].coef[i] * (i + 3);
- for (; i0 >= 0; i0--)
- {
- i = packing[i0];
- pb->geqs[e].coef[i] = pb->geqs[e].coef[i] / g;
- hashCode = hashCode * hash_key_multiplier * (i + 3)
- + pb->geqs[e].coef[i];
- }
- }
- g2 = abs (hashCode);
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file, "Hash code = %d, eqn = ", hashCode);
- omega_print_geq (dump_file, pb, &pb->geqs[e]);
- fprintf (dump_file, "\n");
- }
- j = g2 % HASH_TABLE_SIZE;
- do {
- eqn proto = &(hash_master[j]);
- if (proto->touched == g2)
- {
- if (proto->coef[0] == top_var)
- {
- if (hashCode >= 0)
- for (i0 = top_var; i0 >= 0; i0--)
- {
- i = packing[i0];
- if (pb->geqs[e].coef[i] != proto->coef[i])
- break;
- }
- else
- for (i0 = top_var; i0 >= 0; i0--)
- {
- i = packing[i0];
- if (pb->geqs[e].coef[i] != -proto->coef[i])
- break;
- }
- if (i0 < 0)
- {
- if (hashCode >= 0)
- pb->geqs[e].key = proto->key;
- else
- pb->geqs[e].key = -proto->key;
- break;
- }
- }
- }
- else if (proto->touched < 0)
- {
- omega_init_eqn_zero (proto, pb->num_vars);
- if (hashCode >= 0)
- for (i0 = top_var; i0 >= 0; i0--)
- {
- i = packing[i0];
- proto->coef[i] = pb->geqs[e].coef[i];
- }
- else
- for (i0 = top_var; i0 >= 0; i0--)
- {
- i = packing[i0];
- proto->coef[i] = -pb->geqs[e].coef[i];
- }
- proto->coef[0] = top_var;
- proto->touched = g2;
- if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file, " constraint key = %d\n",
- next_key);
- proto->key = next_key++;
- /* Too many hash keys generated. */
- gcc_assert (proto->key <= MAX_KEYS);
- if (hashCode >= 0)
- pb->geqs[e].key = proto->key;
- else
- pb->geqs[e].key = -proto->key;
- break;
- }
- j = (j + 1) % HASH_TABLE_SIZE;
- } while (1);
- }
- pb->geqs[e].touched = 0;
- }
- {
- int eKey = pb->geqs[e].key;
- int e2;
- if (e > 0)
- {
- int cTerm = pb->geqs[e].coef[0];
- e2 = fast_lookup[MAX_KEYS - eKey];
- if (e2 < e && pb->geqs[e2].key == -eKey
- && pb->geqs[e2].color == omega_black)
- {
- if (pb->geqs[e2].coef[0] < -cTerm)
- {
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- omega_print_geq (dump_file, pb, &pb->geqs[e]);
- fprintf (dump_file, "\n");
- omega_print_geq (dump_file, pb, &pb->geqs[e2]);
- fprintf (dump_file,
- "\nequations have no solution \n");
- }
- return normalize_false;
- }
- if (pb->geqs[e2].coef[0] == -cTerm
- && (create_color
- || pb->geqs[e].color == omega_black))
- {
- omega_copy_eqn (&pb->eqs[pb->num_eqs], &pb->geqs[e],
- pb->num_vars);
- if (pb->geqs[e].color == omega_black)
- adding_equality_constraint (pb, pb->num_eqs);
- pb->num_eqs++;
- gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
- }
- }
- e2 = fast_lookup_red[MAX_KEYS - eKey];
- if (e2 < e && pb->geqs[e2].key == -eKey
- && pb->geqs[e2].color == omega_red)
- {
- if (pb->geqs[e2].coef[0] < -cTerm)
- {
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- omega_print_geq (dump_file, pb, &pb->geqs[e]);
- fprintf (dump_file, "\n");
- omega_print_geq (dump_file, pb, &pb->geqs[e2]);
- fprintf (dump_file,
- "\nequations have no solution \n");
- }
- return normalize_false;
- }
- if (pb->geqs[e2].coef[0] == -cTerm && create_color)
- {
- omega_copy_eqn (&pb->eqs[pb->num_eqs], &pb->geqs[e],
- pb->num_vars);
- pb->eqs[pb->num_eqs].color = omega_red;
- pb->num_eqs++;
- gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
- }
- }
- e2 = fast_lookup[MAX_KEYS + eKey];
- if (e2 < e && pb->geqs[e2].key == eKey
- && pb->geqs[e2].color == omega_black)
- {
- if (pb->geqs[e2].coef[0] > cTerm)
- {
- if (pb->geqs[e].color == omega_black)
- {
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file,
- "Removing Redundant Equation: ");
- omega_print_geq (dump_file, pb, &(pb->geqs[e2]));
- fprintf (dump_file, "\n");
- fprintf (dump_file,
- "[a] Made Redundant by: ");
- omega_print_geq (dump_file, pb, &(pb->geqs[e]));
- fprintf (dump_file, "\n");
- }
- pb->geqs[e2].coef[0] = cTerm;
- omega_delete_geq (pb, e, n_vars);
- e--;
- continue;
- }
- }
- else
- {
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file, "Removing Redundant Equation: ");
- omega_print_geq (dump_file, pb, &(pb->geqs[e]));
- fprintf (dump_file, "\n");
- fprintf (dump_file, "[b] Made Redundant by: ");
- omega_print_geq (dump_file, pb, &(pb->geqs[e2]));
- fprintf (dump_file, "\n");
- }
- omega_delete_geq (pb, e, n_vars);
- e--;
- continue;
- }
- }
- e2 = fast_lookup_red[MAX_KEYS + eKey];
- if (e2 < e && pb->geqs[e2].key == eKey
- && pb->geqs[e2].color == omega_red)
- {
- if (pb->geqs[e2].coef[0] >= cTerm)
- {
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file, "Removing Redundant Equation: ");
- omega_print_geq (dump_file, pb, &(pb->geqs[e2]));
- fprintf (dump_file, "\n");
- fprintf (dump_file, "[c] Made Redundant by: ");
- omega_print_geq (dump_file, pb, &(pb->geqs[e]));
- fprintf (dump_file, "\n");
- }
- pb->geqs[e2].coef[0] = cTerm;
- pb->geqs[e2].color = pb->geqs[e].color;
- }
- else if (pb->geqs[e].color == omega_red)
- {
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file, "Removing Redundant Equation: ");
- omega_print_geq (dump_file, pb, &(pb->geqs[e]));
- fprintf (dump_file, "\n");
- fprintf (dump_file, "[d] Made Redundant by: ");
- omega_print_geq (dump_file, pb, &(pb->geqs[e2]));
- fprintf (dump_file, "\n");
- }
- }
- omega_delete_geq (pb, e, n_vars);
- e--;
- continue;
- }
- }
- if (pb->geqs[e].color == omega_red)
- fast_lookup_red[MAX_KEYS + eKey] = e;
- else
- fast_lookup[MAX_KEYS + eKey] = e;
- }
- }
- create_color = false;
- return coupled_subscripts ? normalize_coupled : normalize_uncoupled;
- }
- /* Divide the coefficients of EQN by their gcd. N_VARS is the number
- of variables in EQN. */
- static inline void
- divide_eqn_by_gcd (eqn eqn, int n_vars)
- {
- int var, g = 0;
- for (var = n_vars; var >= 0; var--)
- g = gcd (abs (eqn->coef[var]), g);
- if (g)
- for (var = n_vars; var >= 0; var--)
- eqn->coef[var] = eqn->coef[var] / g;
- }
- /* Rewrite some non-safe variables in function of protected
- wildcard variables. */
- static void
- cleanout_wildcards (omega_pb pb)
- {
- int e, i, j;
- int n_vars = pb->num_vars;
- bool renormalize = false;
- for (e = pb->num_eqs - 1; e >= 0; e--)
- for (i = n_vars; !omega_safe_var_p (pb, i); i--)
- if (pb->eqs[e].coef[i] != 0)
- {
- /* i is the last nonzero non-safe variable. */
- for (j = i - 1; !omega_safe_var_p (pb, j); j--)
- if (pb->eqs[e].coef[j] != 0)
- break;
- /* j is the next nonzero non-safe variable, or points
- to a safe variable: it is then a wildcard variable. */
- /* Clean it out. */
- if (omega_safe_var_p (pb, j))
- {
- eqn sub = &(pb->eqs[e]);
- int c = pb->eqs[e].coef[i];
- int a = abs (c);
- int e2;
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file,
- "Found a single wild card equality: ");
- omega_print_eq (dump_file, pb, &pb->eqs[e]);
- fprintf (dump_file, "\n");
- omega_print_problem (dump_file, pb);
- }
- for (e2 = pb->num_eqs - 1; e2 >= 0; e2--)
- if (e != e2 && pb->eqs[e2].coef[i]
- && (pb->eqs[e2].color == omega_red
- || (pb->eqs[e2].color == omega_black
- && pb->eqs[e].color == omega_black)))
- {
- eqn eqn = &(pb->eqs[e2]);
- int var, k;
- for (var = n_vars; var >= 0; var--)
- eqn->coef[var] *= a;
- k = eqn->coef[i];
- for (var = n_vars; var >= 0; var--)
- eqn->coef[var] -= sub->coef[var] * k / c;
- eqn->coef[i] = 0;
- divide_eqn_by_gcd (eqn, n_vars);
- }
- for (e2 = pb->num_geqs - 1; e2 >= 0; e2--)
- if (pb->geqs[e2].coef[i]
- && (pb->geqs[e2].color == omega_red
- || (pb->eqs[e].color == omega_black
- && pb->geqs[e2].color == omega_black)))
- {
- eqn eqn = &(pb->geqs[e2]);
- int var, k;
- for (var = n_vars; var >= 0; var--)
- eqn->coef[var] *= a;
- k = eqn->coef[i];
- for (var = n_vars; var >= 0; var--)
- eqn->coef[var] -= sub->coef[var] * k / c;
- eqn->coef[i] = 0;
- eqn->touched = 1;
- renormalize = true;
- }
- for (e2 = pb->num_subs - 1; e2 >= 0; e2--)
- if (pb->subs[e2].coef[i]
- && (pb->subs[e2].color == omega_red
- || (pb->subs[e2].color == omega_black
- && pb->eqs[e].color == omega_black)))
- {
- eqn eqn = &(pb->subs[e2]);
- int var, k;
- for (var = n_vars; var >= 0; var--)
- eqn->coef[var] *= a;
- k = eqn->coef[i];
- for (var = n_vars; var >= 0; var--)
- eqn->coef[var] -= sub->coef[var] * k / c;
- eqn->coef[i] = 0;
- divide_eqn_by_gcd (eqn, n_vars);
- }
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file, "cleaned-out wildcard: ");
- omega_print_problem (dump_file, pb);
- }
- break;
- }
- }
- if (renormalize)
- normalize_omega_problem (pb);
- }
- /* Swap values contained in I and J. */
- static inline void
- swap (int *i, int *j)
- {
- int tmp;
- tmp = *i;
- *i = *j;
- *j = tmp;
- }
- /* Swap values contained in I and J. */
- static inline void
- bswap (bool *i, bool *j)
- {
- bool tmp;
- tmp = *i;
- *i = *j;
- *j = tmp;
- }
- /* Make variable IDX unprotected in PB, by swapping its index at the
- PB->safe_vars rank. */
- static inline void
- omega_unprotect_1 (omega_pb pb, int *idx, bool *unprotect)
- {
- /* If IDX is protected... */
- if (*idx < pb->safe_vars)
- {
- /* ... swap its index with the last non protected index. */
- int j = pb->safe_vars;
- int e;
- for (e = pb->num_geqs - 1; e >= 0; e--)
- {
- pb->geqs[e].touched = 1;
- swap (&pb->geqs[e].coef[*idx], &pb->geqs[e].coef[j]);
- }
- for (e = pb->num_eqs - 1; e >= 0; e--)
- swap (&pb->eqs[e].coef[*idx], &pb->eqs[e].coef[j]);
- for (e = pb->num_subs - 1; e >= 0; e--)
- swap (&pb->subs[e].coef[*idx], &pb->subs[e].coef[j]);
- if (unprotect)
- bswap (&unprotect[*idx], &unprotect[j]);
- swap (&pb->var[*idx], &pb->var[j]);
- pb->forwarding_address[pb->var[*idx]] = *idx;
- pb->forwarding_address[pb->var[j]] = j;
- (*idx)--;
- }
- /* The variable at pb->safe_vars is also unprotected now. */
- pb->safe_vars--;
- }
- /* During the Fourier-Motzkin elimination some variables are
- substituted with other variables. This function resurrects the
- substituted variables in PB. */
- static void
- resurrect_subs (omega_pb pb)
- {
- if (pb->num_subs > 0
- && please_no_equalities_in_simplified_problems == 0)
- {
- int i, e, m;
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file,
- "problem reduced, bringing variables back to life\n");
- omega_print_problem (dump_file, pb);
- }
- for (i = 1; omega_safe_var_p (pb, i); i++)
- if (omega_wildcard_p (pb, i))
- omega_unprotect_1 (pb, &i, NULL);
- m = pb->num_subs;
- for (e = pb->num_geqs - 1; e >= 0; e--)
- if (single_var_geq (&pb->geqs[e], pb->num_vars))
- {
- if (!omega_safe_var_p (pb, abs (pb->geqs[e].key)))
- pb->geqs[e].key += (pb->geqs[e].key > 0 ? m : -m);
- }
- else
- {
- pb->geqs[e].touched = 1;
- pb->geqs[e].key = 0;
- }
- for (i = pb->num_vars; !omega_safe_var_p (pb, i); i--)
- {
- pb->var[i + m] = pb->var[i];
- for (e = pb->num_geqs - 1; e >= 0; e--)
- pb->geqs[e].coef[i + m] = pb->geqs[e].coef[i];
- for (e = pb->num_eqs - 1; e >= 0; e--)
- pb->eqs[e].coef[i + m] = pb->eqs[e].coef[i];
- for (e = pb->num_subs - 1; e >= 0; e--)
- pb->subs[e].coef[i + m] = pb->subs[e].coef[i];
- }
- for (i = pb->safe_vars + m; !omega_safe_var_p (pb, i); i--)
- {
- for (e = pb->num_geqs - 1; e >= 0; e--)
- pb->geqs[e].coef[i] = 0;
- for (e = pb->num_eqs - 1; e >= 0; e--)
- pb->eqs[e].coef[i] = 0;
- for (e = pb->num_subs - 1; e >= 0; e--)
- pb->subs[e].coef[i] = 0;
- }
- pb->num_vars += m;
- for (e = pb->num_subs - 1; e >= 0; e--)
- {
- pb->var[pb->safe_vars + 1 + e] = pb->subs[e].key;
- omega_copy_eqn (&(pb->eqs[pb->num_eqs]), &(pb->subs[e]),
- pb->num_vars);
- pb->eqs[pb->num_eqs].coef[pb->safe_vars + 1 + e] = -1;
- pb->eqs[pb->num_eqs].color = omega_black;
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file, "brought back: ");
- omega_print_eq (dump_file, pb, &pb->eqs[pb->num_eqs]);
- fprintf (dump_file, "\n");
- }
- pb->num_eqs++;
- gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
- }
- pb->safe_vars += m;
- pb->num_subs = 0;
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file, "variables brought back to life\n");
- omega_print_problem (dump_file, pb);
- }
- cleanout_wildcards (pb);
- }
- }
- static inline bool
- implies (unsigned int a, unsigned int b)
- {
- return (a == (a & b));
- }
- /* Eliminate redundant equations in PB. When EXPENSIVE is true, an
- extra step is performed. Returns omega_false when there exist no
- solution, omega_true otherwise. */
- enum omega_result
- omega_eliminate_redundant (omega_pb pb, bool expensive)
- {
- int c, e, e1, e2, e3, p, q, i, k, alpha, alpha1, alpha2, alpha3;
- bool *is_dead = XNEWVEC (bool, OMEGA_MAX_GEQS);
- omega_pb tmp_problem;
- /* {P,Z,N}EQS = {Positive,Zero,Negative} Equations. */
- unsigned int *peqs = XNEWVEC (unsigned int, OMEGA_MAX_GEQS);
- unsigned int *zeqs = XNEWVEC (unsigned int, OMEGA_MAX_GEQS);
- unsigned int *neqs = XNEWVEC (unsigned int, OMEGA_MAX_GEQS);
- /* PP = Possible Positives, PZ = Possible Zeros, PN = Possible Negatives */
- unsigned int pp, pz, pn;
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file, "in eliminate Redundant:\n");
- omega_print_problem (dump_file, pb);
- }
- for (e = pb->num_geqs - 1; e >= 0; e--)
- {
- int tmp = 1;
- is_dead[e] = false;
- peqs[e] = zeqs[e] = neqs[e] = 0;
- for (i = pb->num_vars; i >= 1; i--)
- {
- if (pb->geqs[e].coef[i] > 0)
- peqs[e] |= tmp;
- else if (pb->geqs[e].coef[i] < 0)
- neqs[e] |= tmp;
- else
- zeqs[e] |= tmp;
- tmp <<= 1;
- }
- }
- for (e1 = pb->num_geqs - 1; e1 >= 0; e1--)
- if (!is_dead[e1])
- for (e2 = e1 - 1; e2 >= 0; e2--)
- if (!is_dead[e2])
- {
- for (p = pb->num_vars; p > 1; p--)
- for (q = p - 1; q > 0; q--)
- if ((alpha = pb->geqs[e1].coef[p] * pb->geqs[e2].coef[q]
- - pb->geqs[e2].coef[p] * pb->geqs[e1].coef[q]) != 0)
- goto foundPQ;
- continue;
- foundPQ:
- pz = ((zeqs[e1] & zeqs[e2]) | (peqs[e1] & neqs[e2])
- | (neqs[e1] & peqs[e2]));
- pp = peqs[e1] | peqs[e2];
- pn = neqs[e1] | neqs[e2];
- for (e3 = pb->num_geqs - 1; e3 >= 0; e3--)
- if (e3 != e1 && e3 != e2)
- {
- if (!implies (zeqs[e3], pz))
- goto nextE3;
- alpha1 = (pb->geqs[e2].coef[q] * pb->geqs[e3].coef[p]
- - pb->geqs[e2].coef[p] * pb->geqs[e3].coef[q]);
- alpha2 = -(pb->geqs[e1].coef[q] * pb->geqs[e3].coef[p]
- - pb->geqs[e1].coef[p] * pb->geqs[e3].coef[q]);
- alpha3 = alpha;
- if (alpha1 * alpha2 <= 0)
- goto nextE3;
- if (alpha1 < 0)
- {
- alpha1 = -alpha1;
- alpha2 = -alpha2;
- alpha3 = -alpha3;
- }
- if (alpha3 > 0)
- {
- /* Trying to prove e3 is redundant. */
- if (!implies (peqs[e3], pp)
- || !implies (neqs[e3], pn))
- goto nextE3;
- if (pb->geqs[e3].color == omega_black
- && (pb->geqs[e1].color == omega_red
- || pb->geqs[e2].color == omega_red))
- goto nextE3;
- for (k = pb->num_vars; k >= 1; k--)
- if (alpha3 * pb->geqs[e3].coef[k]
- != (alpha1 * pb->geqs[e1].coef[k]
- + alpha2 * pb->geqs[e2].coef[k]))
- goto nextE3;
- c = (alpha1 * pb->geqs[e1].coef[0]
- + alpha2 * pb->geqs[e2].coef[0]);
- if (c < alpha3 * (pb->geqs[e3].coef[0] + 1))
- {
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file,
- "found redundant inequality\n");
- fprintf (dump_file,
- "alpha1, alpha2, alpha3 = %d,%d,%d\n",
- alpha1, alpha2, alpha3);
- omega_print_geq (dump_file, pb, &(pb->geqs[e1]));
- fprintf (dump_file, "\n");
- omega_print_geq (dump_file, pb, &(pb->geqs[e2]));
- fprintf (dump_file, "\n=> ");
- omega_print_geq (dump_file, pb, &(pb->geqs[e3]));
- fprintf (dump_file, "\n\n");
- }
- is_dead[e3] = true;
- }
- }
- else
- {
- /* Trying to prove e3 <= 0 and therefore e3 = 0,
- or trying to prove e3 < 0, and therefore the
- problem has no solutions. */
- if (!implies (peqs[e3], pn)
- || !implies (neqs[e3], pp))
- goto nextE3;
- if (pb->geqs[e1].color == omega_red
- || pb->geqs[e2].color == omega_red
- || pb->geqs[e3].color == omega_red)
- goto nextE3;
- /* verify alpha1*v1+alpha2*v2 = alpha3*v3 */
- for (k = pb->num_vars; k >= 1; k--)
- if (alpha3 * pb->geqs[e3].coef[k]
- != (alpha1 * pb->geqs[e1].coef[k]
- + alpha2 * pb->geqs[e2].coef[k]))
- goto nextE3;
- c = (alpha1 * pb->geqs[e1].coef[0]
- + alpha2 * pb->geqs[e2].coef[0]);
- if (c < alpha3 * (pb->geqs[e3].coef[0]))
- {
- /* We just proved e3 < 0, so no solutions exist. */
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file,
- "found implied over tight inequality\n");
- fprintf (dump_file,
- "alpha1, alpha2, alpha3 = %d,%d,%d\n",
- alpha1, alpha2, -alpha3);
- omega_print_geq (dump_file, pb, &(pb->geqs[e1]));
- fprintf (dump_file, "\n");
- omega_print_geq (dump_file, pb, &(pb->geqs[e2]));
- fprintf (dump_file, "\n=> not ");
- omega_print_geq (dump_file, pb, &(pb->geqs[e3]));
- fprintf (dump_file, "\n\n");
- }
- free (is_dead);
- free (peqs);
- free (zeqs);
- free (neqs);
- return omega_false;
- }
- else if (c < alpha3 * (pb->geqs[e3].coef[0] - 1))
- {
- /* We just proved that e3 <=0, so e3 = 0. */
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file,
- "found implied tight inequality\n");
- fprintf (dump_file,
- "alpha1, alpha2, alpha3 = %d,%d,%d\n",
- alpha1, alpha2, -alpha3);
- omega_print_geq (dump_file, pb, &(pb->geqs[e1]));
- fprintf (dump_file, "\n");
- omega_print_geq (dump_file, pb, &(pb->geqs[e2]));
- fprintf (dump_file, "\n=> inverse ");
- omega_print_geq (dump_file, pb, &(pb->geqs[e3]));
- fprintf (dump_file, "\n\n");
- }
- omega_copy_eqn (&pb->eqs[pb->num_eqs++],
- &pb->geqs[e3], pb->num_vars);
- gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
- adding_equality_constraint (pb, pb->num_eqs - 1);
- is_dead[e3] = true;
- }
- }
- nextE3:;
- }
- }
- /* Delete the inequalities that were marked as dead. */
- for (e = pb->num_geqs - 1; e >= 0; e--)
- if (is_dead[e])
- omega_delete_geq (pb, e, pb->num_vars);
- if (!expensive)
- goto eliminate_redundant_done;
- tmp_problem = XNEW (struct omega_pb_d);
- conservative++;
- for (e = pb->num_geqs - 1; e >= 0; e--)
- {
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file,
- "checking equation %d to see if it is redundant: ", e);
- omega_print_geq (dump_file, pb, &(pb->geqs[e]));
- fprintf (dump_file, "\n");
- }
- omega_copy_problem (tmp_problem, pb);
- omega_negate_geq (tmp_problem, e);
- tmp_problem->safe_vars = 0;
- tmp_problem->variables_freed = false;
- if (omega_solve_problem (tmp_problem, omega_false) == omega_false)
- omega_delete_geq (pb, e, pb->num_vars);
- }
- free (tmp_problem);
- conservative--;
- if (!omega_reduce_with_subs)
- {
- resurrect_subs (pb);
- gcc_assert (please_no_equalities_in_simplified_problems
- || pb->num_subs == 0);
- }
- eliminate_redundant_done:
- free (is_dead);
- free (peqs);
- free (zeqs);
- free (neqs);
- return omega_true;
- }
- /* For each inequality that has coefficients bigger than 20, try to
- create a new constraint that cannot be derived from the original
- constraint and that has smaller coefficients. Add the new
- constraint at the end of geqs. Return the number of inequalities
- that have been added to PB. */
- static int
- smooth_weird_equations (omega_pb pb)
- {
- int e1, e2, e3, p, q, k, alpha, alpha1, alpha2, alpha3;
- int c;
- int v;
- int result = 0;
- for (e1 = pb->num_geqs - 1; e1 >= 0; e1--)
- if (pb->geqs[e1].color == omega_black)
- {
- int g = 999999;
- for (v = pb->num_vars; v >= 1; v--)
- if (pb->geqs[e1].coef[v] != 0 && abs (pb->geqs[e1].coef[v]) < g)
- g = abs (pb->geqs[e1].coef[v]);
- /* Magic number. */
- if (g > 20)
- {
- e3 = pb->num_geqs;
- for (v = pb->num_vars; v >= 1; v--)
- pb->geqs[e3].coef[v] = int_div (6 * pb->geqs[e1].coef[v] + g / 2,
- g);
- pb->geqs[e3].color = omega_black;
- pb->geqs[e3].touched = 1;
- /* Magic number. */
- pb->geqs[e3].coef[0] = 9997;
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file, "Checking to see if we can derive: ");
- omega_print_geq (dump_file, pb, &pb->geqs[e3]);
- fprintf (dump_file, "\n from: ");
- omega_print_geq (dump_file, pb, &pb->geqs[e1]);
- fprintf (dump_file, "\n");
- }
- for (e2 = pb->num_geqs - 1; e2 >= 0; e2--)
- if (e1 != e2 && pb->geqs[e2].color == omega_black)
- {
- for (p = pb->num_vars; p > 1; p--)
- {
- for (q = p - 1; q > 0; q--)
- {
- alpha =
- (pb->geqs[e1].coef[p] * pb->geqs[e2].coef[q] -
- pb->geqs[e2].coef[p] * pb->geqs[e1].coef[q]);
- if (alpha != 0)
- goto foundPQ;
- }
- }
- continue;
- foundPQ:
- alpha1 = (pb->geqs[e2].coef[q] * pb->geqs[e3].coef[p]
- - pb->geqs[e2].coef[p] * pb->geqs[e3].coef[q]);
- alpha2 = -(pb->geqs[e1].coef[q] * pb->geqs[e3].coef[p]
- - pb->geqs[e1].coef[p] * pb->geqs[e3].coef[q]);
- alpha3 = alpha;
- if (alpha1 * alpha2 <= 0)
- continue;
- if (alpha1 < 0)
- {
- alpha1 = -alpha1;
- alpha2 = -alpha2;
- alpha3 = -alpha3;
- }
- if (alpha3 > 0)
- {
- /* Try to prove e3 is redundant: verify
- alpha1*v1 + alpha2*v2 = alpha3*v3. */
- for (k = pb->num_vars; k >= 1; k--)
- if (alpha3 * pb->geqs[e3].coef[k]
- != (alpha1 * pb->geqs[e1].coef[k]
- + alpha2 * pb->geqs[e2].coef[k]))
- goto nextE2;
- c = alpha1 * pb->geqs[e1].coef[0]
- + alpha2 * pb->geqs[e2].coef[0];
- if (c < alpha3 * (pb->geqs[e3].coef[0] + 1))
- pb->geqs[e3].coef[0] = int_div (c, alpha3);
- }
- nextE2:;
- }
- if (pb->geqs[e3].coef[0] < 9997)
- {
- result++;
- pb->num_geqs++;
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file,
- "Smoothing weird equations; adding:\n");
- omega_print_geq (dump_file, pb, &pb->geqs[e3]);
- fprintf (dump_file, "\nto:\n");
- omega_print_problem (dump_file, pb);
- fprintf (dump_file, "\n\n");
- }
- }
- }
- }
- return result;
- }
- /* Replace tuples of inequalities, that define upper and lower half
- spaces, with an equation. */
- static void
- coalesce (omega_pb pb)
- {
- int e, e2;
- int colors = 0;
- bool *is_dead;
- int found_something = 0;
- for (e = 0; e < pb->num_geqs; e++)
- if (pb->geqs[e].color == omega_red)
- colors++;
- if (colors < 2)
- return;
- is_dead = XNEWVEC (bool, OMEGA_MAX_GEQS);
- for (e = 0; e < pb->num_geqs; e++)
- is_dead[e] = false;
- for (e = 0; e < pb->num_geqs; e++)
- if (pb->geqs[e].color == omega_red
- && !pb->geqs[e].touched)
- for (e2 = e + 1; e2 < pb->num_geqs; e2++)
- if (!pb->geqs[e2].touched
- && pb->geqs[e].key == -pb->geqs[e2].key
- && pb->geqs[e].coef[0] == -pb->geqs[e2].coef[0]
- && pb->geqs[e2].color == omega_red)
- {
- omega_copy_eqn (&pb->eqs[pb->num_eqs++], &pb->geqs[e],
- pb->num_vars);
- gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
- found_something++;
- is_dead[e] = true;
- is_dead[e2] = true;
- }
- for (e = pb->num_geqs - 1; e >= 0; e--)
- if (is_dead[e])
- omega_delete_geq (pb, e, pb->num_vars);
- if (dump_file && (dump_flags & TDF_DETAILS) && found_something)
- {
- fprintf (dump_file, "Coalesced pb->geqs into %d EQ's:\n",
- found_something);
- omega_print_problem (dump_file, pb);
- }
- free (is_dead);
- }
- /* Eliminate red inequalities from PB. When ELIMINATE_ALL is
- true, continue to eliminate all the red inequalities. */
- void
- omega_eliminate_red (omega_pb pb, bool eliminate_all)
- {
- int e, e2, e3, i, j, k, a, alpha1, alpha2;
- int c = 0;
- bool *is_dead = XNEWVEC (bool, OMEGA_MAX_GEQS);
- int dead_count = 0;
- int red_found;
- omega_pb tmp_problem;
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file, "in eliminate RED:\n");
- omega_print_problem (dump_file, pb);
- }
- if (pb->num_eqs > 0)
- omega_simplify_problem (pb);
- for (e = pb->num_geqs - 1; e >= 0; e--)
- is_dead[e] = false;
- for (e = pb->num_geqs - 1; e >= 0; e--)
- if (pb->geqs[e].color == omega_black && !is_dead[e])
- for (e2 = e - 1; e2 >= 0; e2--)
- if (pb->geqs[e2].color == omega_black
- && !is_dead[e2])
- {
- a = 0;
- for (i = pb->num_vars; i > 1; i--)
- for (j = i - 1; j > 0; j--)
- if ((a = (pb->geqs[e].coef[i] * pb->geqs[e2].coef[j]
- - pb->geqs[e2].coef[i] * pb->geqs[e].coef[j])) != 0)
- goto found_pair;
- continue;
- found_pair:
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file,
- "found two equations to combine, i = %s, ",
- omega_variable_to_str (pb, i));
- fprintf (dump_file, "j = %s, alpha = %d\n",
- omega_variable_to_str (pb, j), a);
- omega_print_geq (dump_file, pb, &(pb->geqs[e]));
- fprintf (dump_file, "\n");
- omega_print_geq (dump_file, pb, &(pb->geqs[e2]));
- fprintf (dump_file, "\n");
- }
- for (e3 = pb->num_geqs - 1; e3 >= 0; e3--)
- if (pb->geqs[e3].color == omega_red)
- {
- alpha1 = (pb->geqs[e2].coef[j] * pb->geqs[e3].coef[i]
- - pb->geqs[e2].coef[i] * pb->geqs[e3].coef[j]);
- alpha2 = -(pb->geqs[e].coef[j] * pb->geqs[e3].coef[i]
- - pb->geqs[e].coef[i] * pb->geqs[e3].coef[j]);
- if ((a > 0 && alpha1 > 0 && alpha2 > 0)
- || (a < 0 && alpha1 < 0 && alpha2 < 0))
- {
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file,
- "alpha1 = %d, alpha2 = %d;"
- "comparing against: ",
- alpha1, alpha2);
- omega_print_geq (dump_file, pb, &(pb->geqs[e3]));
- fprintf (dump_file, "\n");
- }
- for (k = pb->num_vars; k >= 0; k--)
- {
- c = (alpha1 * pb->geqs[e].coef[k]
- + alpha2 * pb->geqs[e2].coef[k]);
- if (c != a * pb->geqs[e3].coef[k])
- break;
- if (dump_file && (dump_flags & TDF_DETAILS) && k > 0)
- fprintf (dump_file, " %s: %d, %d\n",
- omega_variable_to_str (pb, k), c,
- a * pb->geqs[e3].coef[k]);
- }
- if (k < 0
- || (k == 0 &&
- ((a > 0 && c < a * pb->geqs[e3].coef[k])
- || (a < 0 && c > a * pb->geqs[e3].coef[k]))))
- {
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- dead_count++;
- fprintf (dump_file,
- "red equation#%d is dead "
- "(%d dead so far, %d remain)\n",
- e3, dead_count,
- pb->num_geqs - dead_count);
- omega_print_geq (dump_file, pb, &(pb->geqs[e]));
- fprintf (dump_file, "\n");
- omega_print_geq (dump_file, pb, &(pb->geqs[e2]));
- fprintf (dump_file, "\n");
- omega_print_geq (dump_file, pb, &(pb->geqs[e3]));
- fprintf (dump_file, "\n");
- }
- is_dead[e3] = true;
- }
- }
- }
- }
- for (e = pb->num_geqs - 1; e >= 0; e--)
- if (is_dead[e])
- omega_delete_geq (pb, e, pb->num_vars);
- free (is_dead);
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file, "in eliminate RED, easy tests done:\n");
- omega_print_problem (dump_file, pb);
- }
- for (red_found = 0, e = pb->num_geqs - 1; e >= 0; e--)
- if (pb->geqs[e].color == omega_red)
- {
- red_found = 1;
- break;
- }
- if (!red_found)
- {
- if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file, "fast checks worked\n");
- if (!omega_reduce_with_subs)
- gcc_assert (please_no_equalities_in_simplified_problems
- || pb->num_subs == 0);
- return;
- }
- if (!omega_verify_simplification
- && verify_omega_pb (pb) == omega_false)
- return;
- conservative++;
- tmp_problem = XNEW (struct omega_pb_d);
- for (e = pb->num_geqs - 1; e >= 0; e--)
- if (pb->geqs[e].color == omega_red)
- {
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file,
- "checking equation %d to see if it is redundant: ", e);
- omega_print_geq (dump_file, pb, &(pb->geqs[e]));
- fprintf (dump_file, "\n");
- }
- omega_copy_problem (tmp_problem, pb);
- omega_negate_geq (tmp_problem, e);
- tmp_problem->safe_vars = 0;
- tmp_problem->variables_freed = false;
- tmp_problem->num_subs = 0;
- if (omega_solve_problem (tmp_problem, omega_false) == omega_false)
- {
- if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file, "it is redundant\n");
- omega_delete_geq (pb, e, pb->num_vars);
- }
- else
- {
- if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file, "it is not redundant\n");
- if (!eliminate_all)
- {
- if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file, "no need to check other red equations\n");
- break;
- }
- }
- }
- conservative--;
- free (tmp_problem);
- /* omega_simplify_problem (pb); */
- if (!omega_reduce_with_subs)
- gcc_assert (please_no_equalities_in_simplified_problems
- || pb->num_subs == 0);
- }
- /* Transform some wildcard variables to non-safe variables. */
- static void
- chain_unprotect (omega_pb pb)
- {
- int i, e;
- bool *unprotect = XNEWVEC (bool, OMEGA_MAX_VARS);
- for (i = 1; omega_safe_var_p (pb, i); i++)
- {
- unprotect[i] = omega_wildcard_p (pb, i);
- for (e = pb->num_subs - 1; e >= 0; e--)
- if (pb->subs[e].coef[i])
- unprotect[i] = false;
- }
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file, "Doing chain reaction unprotection\n");
- omega_print_problem (dump_file, pb);
- for (i = 1; omega_safe_var_p (pb, i); i++)
- if (unprotect[i])
- fprintf (dump_file, "unprotecting %s\n",
- omega_variable_to_str (pb, i));
- }
- for (i = 1; omega_safe_var_p (pb, i); i++)
- if (unprotect[i])
- omega_unprotect_1 (pb, &i, unprotect);
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file, "After chain reactions\n");
- omega_print_problem (dump_file, pb);
- }
- free (unprotect);
- }
- /* Reduce problem PB. */
- static void
- omega_problem_reduced (omega_pb pb)
- {
- if (omega_verify_simplification
- && !in_approximate_mode
- && verify_omega_pb (pb) == omega_false)
- return;
- if (PARAM_VALUE (PARAM_OMEGA_ELIMINATE_REDUNDANT_CONSTRAINTS)
- && !omega_eliminate_redundant (pb, true))
- return;
- omega_found_reduction = omega_true;
- if (!please_no_equalities_in_simplified_problems)
- coalesce (pb);
- if (omega_reduce_with_subs
- || please_no_equalities_in_simplified_problems)
- chain_unprotect (pb);
- else
- resurrect_subs (pb);
- if (!return_single_result)
- {
- int i;
- for (i = 1; omega_safe_var_p (pb, i); i++)
- pb->forwarding_address[pb->var[i]] = i;
- for (i = 0; i < pb->num_subs; i++)
- pb->forwarding_address[pb->subs[i].key] = -i - 1;
- (*omega_when_reduced) (pb);
- }
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file, "-------------------------------------------\n");
- fprintf (dump_file, "problem reduced:\n");
- omega_print_problem (dump_file, pb);
- fprintf (dump_file, "-------------------------------------------\n");
- }
- }
- /* Eliminates all the free variables for problem PB, that is all the
- variables from FV to PB->NUM_VARS. */
- static void
- omega_free_eliminations (omega_pb pb, int fv)
- {
- bool try_again = true;
- int i, e, e2;
- int n_vars = pb->num_vars;
- while (try_again)
- {
- try_again = false;
- for (i = n_vars; i > fv; i--)
- {
- for (e = pb->num_geqs - 1; e >= 0; e--)
- if (pb->geqs[e].coef[i])
- break;
- if (e < 0)
- e2 = e;
- else if (pb->geqs[e].coef[i] > 0)
- {
- for (e2 = e - 1; e2 >= 0; e2--)
- if (pb->geqs[e2].coef[i] < 0)
- break;
- }
- else
- {
- for (e2 = e - 1; e2 >= 0; e2--)
- if (pb->geqs[e2].coef[i] > 0)
- break;
- }
- if (e2 < 0)
- {
- int e3;
- for (e3 = pb->num_subs - 1; e3 >= 0; e3--)
- if (pb->subs[e3].coef[i])
- break;
- if (e3 >= 0)
- continue;
- for (e3 = pb->num_eqs - 1; e3 >= 0; e3--)
- if (pb->eqs[e3].coef[i])
- break;
- if (e3 >= 0)
- continue;
- if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file, "a free elimination of %s\n",
- omega_variable_to_str (pb, i));
- if (e >= 0)
- {
- omega_delete_geq (pb, e, n_vars);
- for (e--; e >= 0; e--)
- if (pb->geqs[e].coef[i])
- omega_delete_geq (pb, e, n_vars);
- try_again = (i < n_vars);
- }
- omega_delete_variable (pb, i);
- n_vars = pb->num_vars;
- }
- }
- }
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file, "\nafter free eliminations:\n");
- omega_print_problem (dump_file, pb);
- fprintf (dump_file, "\n");
- }
- }
- /* Do free red eliminations. */
- static void
- free_red_eliminations (omega_pb pb)
- {
- bool try_again = true;
- int i, e, e2;
- int n_vars = pb->num_vars;
- bool *is_red_var = XNEWVEC (bool, OMEGA_MAX_VARS);
- bool *is_dead_var = XNEWVEC (bool, OMEGA_MAX_VARS);
- bool *is_dead_geq = XNEWVEC (bool, OMEGA_MAX_GEQS);
- for (i = n_vars; i > 0; i--)
- {
- is_red_var[i] = false;
- is_dead_var[i] = false;
- }
- for (e = pb->num_geqs - 1; e >= 0; e--)
- {
- is_dead_geq[e] = false;
- if (pb->geqs[e].color == omega_red)
- for (i = n_vars; i > 0; i--)
- if (pb->geqs[e].coef[i] != 0)
- is_red_var[i] = true;
- }
- while (try_again)
- {
- try_again = false;
- for (i = n_vars; i > 0; i--)
- if (!is_red_var[i] && !is_dead_var[i])
- {
- for (e = pb->num_geqs - 1; e >= 0; e--)
- if (!is_dead_geq[e] && pb->geqs[e].coef[i])
- break;
- if (e < 0)
- e2 = e;
- else if (pb->geqs[e].coef[i] > 0)
- {
- for (e2 = e - 1; e2 >= 0; e2--)
- if (!is_dead_geq[e2] && pb->geqs[e2].coef[i] < 0)
- break;
- }
- else
- {
- for (e2 = e - 1; e2 >= 0; e2--)
- if (!is_dead_geq[e2] && pb->geqs[e2].coef[i] > 0)
- break;
- }
- if (e2 < 0)
- {
- int e3;
- for (e3 = pb->num_subs - 1; e3 >= 0; e3--)
- if (pb->subs[e3].coef[i])
- break;
- if (e3 >= 0)
- continue;
- for (e3 = pb->num_eqs - 1; e3 >= 0; e3--)
- if (pb->eqs[e3].coef[i])
- break;
- if (e3 >= 0)
- continue;
- if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file, "a free red elimination of %s\n",
- omega_variable_to_str (pb, i));
- for (; e >= 0; e--)
- if (pb->geqs[e].coef[i])
- is_dead_geq[e] = true;
- try_again = true;
- is_dead_var[i] = true;
- }
- }
- }
- for (e = pb->num_geqs - 1; e >= 0; e--)
- if (is_dead_geq[e])
- omega_delete_geq (pb, e, n_vars);
- for (i = n_vars; i > 0; i--)
- if (is_dead_var[i])
- omega_delete_variable (pb, i);
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file, "\nafter free red eliminations:\n");
- omega_print_problem (dump_file, pb);
- fprintf (dump_file, "\n");
- }
- free (is_red_var);
- free (is_dead_var);
- free (is_dead_geq);
- }
- /* For equation EQ of the form "0 = EQN", insert in PB two
- inequalities "0 <= EQN" and "0 <= -EQN". */
- void
- omega_convert_eq_to_geqs (omega_pb pb, int eq)
- {
- int i;
- if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file, "Converting Eq to Geqs\n");
- /* Insert "0 <= EQN". */
- omega_copy_eqn (&pb->geqs[pb->num_geqs], &pb->eqs[eq], pb->num_vars);
- pb->geqs[pb->num_geqs].touched = 1;
- pb->num_geqs++;
- /* Insert "0 <= -EQN". */
- omega_copy_eqn (&pb->geqs[pb->num_geqs], &pb->eqs[eq], pb->num_vars);
- pb->geqs[pb->num_geqs].touched = 1;
- for (i = 0; i <= pb->num_vars; i++)
- pb->geqs[pb->num_geqs].coef[i] *= -1;
- pb->num_geqs++;
- if (dump_file && (dump_flags & TDF_DETAILS))
- omega_print_problem (dump_file, pb);
- }
- /* Eliminates variable I from PB. */
- static void
- omega_do_elimination (omega_pb pb, int e, int i)
- {
- eqn sub = omega_alloc_eqns (0, 1);
- int c;
- int n_vars = pb->num_vars;
- if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file, "eliminating variable %s\n",
- omega_variable_to_str (pb, i));
- omega_copy_eqn (sub, &pb->eqs[e], pb->num_vars);
- c = sub->coef[i];
- sub->coef[i] = 0;
- if (c == 1 || c == -1)
- {
- if (pb->eqs[e].color == omega_red)
- {
- bool fB;
- omega_substitute_red (pb, sub, i, c, &fB);
- if (fB)
- omega_convert_eq_to_geqs (pb, e);
- else
- omega_delete_variable (pb, i);
- }
- else
- {
- omega_substitute (pb, sub, i, c);
- omega_delete_variable (pb, i);
- }
- }
- else
- {
- int a = abs (c);
- int e2 = e;
- if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file, "performing non-exact elimination, c = %d\n", c);
- for (e = pb->num_eqs - 1; e >= 0; e--)
- if (pb->eqs[e].coef[i])
- {
- eqn eqn = &(pb->eqs[e]);
- int j, k;
- for (j = n_vars; j >= 0; j--)
- eqn->coef[j] *= a;
- k = eqn->coef[i];
- eqn->coef[i] = 0;
- if (sub->color == omega_red)
- eqn->color = omega_red;
- for (j = n_vars; j >= 0; j--)
- eqn->coef[j] -= sub->coef[j] * k / c;
- }
- for (e = pb->num_geqs - 1; e >= 0; e--)
- if (pb->geqs[e].coef[i])
- {
- eqn eqn = &(pb->geqs[e]);
- int j, k;
- if (sub->color == omega_red)
- eqn->color = omega_red;
- for (j = n_vars; j >= 0; j--)
- eqn->coef[j] *= a;
- eqn->touched = 1;
- k = eqn->coef[i];
- eqn->coef[i] = 0;
- for (j = n_vars; j >= 0; j--)
- eqn->coef[j] -= sub->coef[j] * k / c;
- }
- for (e = pb->num_subs - 1; e >= 0; e--)
- if (pb->subs[e].coef[i])
- {
- eqn eqn = &(pb->subs[e]);
- int j, k;
- gcc_assert (0);
- gcc_assert (sub->color == omega_black);
- for (j = n_vars; j >= 0; j--)
- eqn->coef[j] *= a;
- k = eqn->coef[i];
- eqn->coef[i] = 0;
- for (j = n_vars; j >= 0; j--)
- eqn->coef[j] -= sub->coef[j] * k / c;
- }
- if (in_approximate_mode)
- omega_delete_variable (pb, i);
- else
- omega_convert_eq_to_geqs (pb, e2);
- }
- omega_free_eqns (sub, 1);
- }
- /* Helper function for printing "sorry, no solution". */
- static inline enum omega_result
- omega_problem_has_no_solution (void)
- {
- if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file, "\nequations have no solution \n");
- return omega_false;
- }
- /* Helper function: solve equations in PB one at a time, following the
- DESIRED_RES result. */
- static enum omega_result
- omega_solve_eq (omega_pb pb, enum omega_result desired_res)
- {
- int i, j, e;
- int g, g2;
- g = 0;
- if (dump_file && (dump_flags & TDF_DETAILS) && pb->num_eqs > 0)
- {
- fprintf (dump_file, "\nomega_solve_eq (%d, %d)\n",
- desired_res, may_be_red);
- omega_print_problem (dump_file, pb);
- fprintf (dump_file, "\n");
- }
- if (may_be_red)
- {
- i = 0;
- j = pb->num_eqs - 1;
- while (1)
- {
- eqn eq;
- while (i <= j && pb->eqs[i].color == omega_red)
- i++;
- while (i <= j && pb->eqs[j].color == omega_black)
- j--;
- if (i >= j)
- break;
- eq = omega_alloc_eqns (0, 1);
- omega_copy_eqn (eq, &pb->eqs[i], pb->num_vars);
- omega_copy_eqn (&pb->eqs[i], &pb->eqs[j], pb->num_vars);
- omega_copy_eqn (&pb->eqs[j], eq, pb->num_vars);
- omega_free_eqns (eq, 1);
- i++;
- j--;
- }
- }
- /* Eliminate all EQ equations */
- for (e = pb->num_eqs - 1; e >= 0; e--)
- {
- eqn eqn = &(pb->eqs[e]);
- int sv;
- if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file, "----\n");
- for (i = pb->num_vars; i > 0; i--)
- if (eqn->coef[i])
- break;
- g = eqn->coef[i];
- for (j = i - 1; j > 0; j--)
- if (eqn->coef[j])
- break;
- /* i is the position of last nonzero coefficient,
- g is the coefficient of i,
- j is the position of next nonzero coefficient. */
- if (j == 0)
- {
- if (eqn->coef[0] % g != 0)
- return omega_problem_has_no_solution ();
- eqn->coef[0] = eqn->coef[0] / g;
- eqn->coef[i] = 1;
- pb->num_eqs--;
- omega_do_elimination (pb, e, i);
- continue;
- }
- else if (j == -1)
- {
- if (eqn->coef[0] != 0)
- return omega_problem_has_no_solution ();
- pb->num_eqs--;
- continue;
- }
- if (g < 0)
- g = -g;
- if (g == 1)
- {
- pb->num_eqs--;
- omega_do_elimination (pb, e, i);
- }
- else
- {
- int k = j;
- bool promotion_possible =
- (omega_safe_var_p (pb, j)
- && pb->safe_vars + 1 == i
- && !omega_eqn_is_red (eqn, desired_res)
- && !in_approximate_mode);
- if (dump_file && (dump_flags & TDF_DETAILS) && promotion_possible)
- fprintf (dump_file, " Promotion possible\n");
- normalizeEQ:
- if (!omega_safe_var_p (pb, j))
- {
- for (; g != 1 && !omega_safe_var_p (pb, j); j--)
- g = gcd (abs (eqn->coef[j]), g);
- g2 = g;
- }
- else if (!omega_safe_var_p (pb, i))
- g2 = g;
- else
- g2 = 0;
- for (; g != 1 && j > 0; j--)
- g = gcd (abs (eqn->coef[j]), g);
- if (g > 1)
- {
- if (eqn->coef[0] % g != 0)
- return omega_problem_has_no_solution ();
- for (j = 0; j <= pb->num_vars; j++)
- eqn->coef[j] /= g;
- g2 = g2 / g;
- }
- if (g2 > 1)
- {
- int e2;
- for (e2 = e - 1; e2 >= 0; e2--)
- if (pb->eqs[e2].coef[i])
- break;
- if (e2 == -1)
- for (e2 = pb->num_geqs - 1; e2 >= 0; e2--)
- if (pb->geqs[e2].coef[i])
- break;
- if (e2 == -1)
- for (e2 = pb->num_subs - 1; e2 >= 0; e2--)
- if (pb->subs[e2].coef[i])
- break;
- if (e2 == -1)
- {
- bool change = false;
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file, "Ha! We own it! \n");
- omega_print_eq (dump_file, pb, eqn);
- fprintf (dump_file, " \n");
- }
- g = eqn->coef[i];
- g = abs (g);
- for (j = i - 1; j >= 0; j--)
- {
- int t = int_mod (eqn->coef[j], g);
- if (2 * t >= g)
- t -= g;
- if (t != eqn->coef[j])
- {
- eqn->coef[j] = t;
- change = true;
- }
- }
- if (!change)
- {
- if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file, "So what?\n");
- }
- else
- {
- omega_name_wild_card (pb, i);
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- omega_print_eq (dump_file, pb, eqn);
- fprintf (dump_file, " \n");
- }
- e++;
- continue;
- }
- }
- }
- if (promotion_possible)
- {
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file, "promoting %s to safety\n",
- omega_variable_to_str (pb, i));
- omega_print_vars (dump_file, pb);
- }
- pb->safe_vars++;
- if (!omega_wildcard_p (pb, i))
- omega_name_wild_card (pb, i);
- promotion_possible = false;
- j = k;
- goto normalizeEQ;
- }
- if (g2 > 1 && !in_approximate_mode)
- {
- if (pb->eqs[e].color == omega_red)
- {
- if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file, "handling red equality\n");
- pb->num_eqs--;
- omega_do_elimination (pb, e, i);
- continue;
- }
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file,
- "adding equation to handle safe variable \n");
- omega_print_eq (dump_file, pb, eqn);
- fprintf (dump_file, "\n----\n");
- omega_print_problem (dump_file, pb);
- fprintf (dump_file, "\n----\n");
- fprintf (dump_file, "\n----\n");
- }
- i = omega_add_new_wild_card (pb);
- pb->num_eqs++;
- gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
- omega_init_eqn_zero (&pb->eqs[e + 1], pb->num_vars);
- omega_copy_eqn (&pb->eqs[e + 1], eqn, pb->safe_vars);
- for (j = pb->num_vars; j >= 0; j--)
- {
- pb->eqs[e + 1].coef[j] = int_mod (pb->eqs[e + 1].coef[j], g2);
- if (2 * pb->eqs[e + 1].coef[j] >= g2)
- pb->eqs[e + 1].coef[j] -= g2;
- }
- pb->eqs[e + 1].coef[i] = g2;
- e += 2;
- if (dump_file && (dump_flags & TDF_DETAILS))
- omega_print_problem (dump_file, pb);
- continue;
- }
- sv = pb->safe_vars;
- if (g2 == 0)
- sv = 0;
- /* Find variable to eliminate. */
- if (g2 > 1)
- {
- gcc_assert (in_approximate_mode);
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file, "non-exact elimination: ");
- omega_print_eq (dump_file, pb, eqn);
- fprintf (dump_file, "\n");
- omega_print_problem (dump_file, pb);
- }
- for (i = pb->num_vars; i > sv; i--)
- if (pb->eqs[e].coef[i] != 0)
- break;
- }
- else
- for (i = pb->num_vars; i > sv; i--)
- if (pb->eqs[e].coef[i] == 1 || pb->eqs[e].coef[i] == -1)
- break;
- if (i > sv)
- {
- pb->num_eqs--;
- omega_do_elimination (pb, e, i);
- if (dump_file && (dump_flags & TDF_DETAILS) && g2 > 1)
- {
- fprintf (dump_file, "result of non-exact elimination:\n");
- omega_print_problem (dump_file, pb);
- }
- }
- else
- {
- int factor = (INT_MAX);
- j = 0;
- if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file, "doing moding\n");
- for (i = pb->num_vars; i != sv; i--)
- if ((pb->eqs[e].coef[i] & 1) != 0)
- {
- j = i;
- i--;
- for (; i != sv; i--)
- if ((pb->eqs[e].coef[i] & 1) != 0)
- break;
- break;
- }
- if (j != 0 && i == sv)
- {
- omega_do_mod (pb, 2, e, j);
- e++;
- continue;
- }
- j = 0;
- for (i = pb->num_vars; i != sv; i--)
- if (pb->eqs[e].coef[i] != 0
- && factor > abs (pb->eqs[e].coef[i]) + 1)
- {
- factor = abs (pb->eqs[e].coef[i]) + 1;
- j = i;
- }
- if (j == sv)
- {
- if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file, "should not have happened\n");
- gcc_assert (0);
- }
- omega_do_mod (pb, factor, e, j);
- /* Go back and try this equation again. */
- e++;
- }
- }
- }
- pb->num_eqs = 0;
- return omega_unknown;
- }
- /* Transform an inequation E to an equality, then solve DIFF problems
- based on PB, and only differing by the constant part that is
- diminished by one, trying to figure out which of the constants
- satisfies PB. */
- static enum omega_result
- parallel_splinter (omega_pb pb, int e, int diff,
- enum omega_result desired_res)
- {
- omega_pb tmp_problem;
- int i;
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file, "Using parallel splintering\n");
- omega_print_problem (dump_file, pb);
- }
- tmp_problem = XNEW (struct omega_pb_d);
- omega_copy_eqn (&pb->eqs[0], &pb->geqs[e], pb->num_vars);
- pb->num_eqs = 1;
- for (i = 0; i <= diff; i++)
- {
- omega_copy_problem (tmp_problem, pb);
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file, "Splinter # %i\n", i);
- omega_print_problem (dump_file, pb);
- }
- if (omega_solve_problem (tmp_problem, desired_res) == omega_true)
- {
- free (tmp_problem);
- return omega_true;
- }
- pb->eqs[0].coef[0]--;
- }
- free (tmp_problem);
- return omega_false;
- }
- /* Helper function: solve equations one at a time. */
- static enum omega_result
- omega_solve_geq (omega_pb pb, enum omega_result desired_res)
- {
- int i, e;
- int n_vars, fv;
- enum omega_result result;
- bool coupled_subscripts = false;
- bool smoothed = false;
- bool eliminate_again;
- bool tried_eliminating_redundant = false;
- if (desired_res != omega_simplify)
- {
- pb->num_subs = 0;
- pb->safe_vars = 0;
- }
- solve_geq_start:
- do {
- gcc_assert (desired_res == omega_simplify || pb->num_subs == 0);
- /* Verify that there are not too many inequalities. */
- gcc_assert (pb->num_geqs <= OMEGA_MAX_GEQS);
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file, "\nomega_solve_geq (%d,%d):\n",
- desired_res, please_no_equalities_in_simplified_problems);
- omega_print_problem (dump_file, pb);
- fprintf (dump_file, "\n");
- }
- n_vars = pb->num_vars;
- if (n_vars == 1)
- {
- enum omega_eqn_color u_color = omega_black;
- enum omega_eqn_color l_color = omega_black;
- int upper_bound = pos_infinity;
- int lower_bound = neg_infinity;
- for (e = pb->num_geqs - 1; e >= 0; e--)
- {
- int a = pb->geqs[e].coef[1];
- int c = pb->geqs[e].coef[0];
- /* Our equation is ax + c >= 0, or ax >= -c, or c >= -ax. */
- if (a == 0)
- {
- if (c < 0)
- return omega_problem_has_no_solution ();
- }
- else if (a > 0)
- {
- if (a != 1)
- c = int_div (c, a);
- if (lower_bound < -c
- || (lower_bound == -c
- && !omega_eqn_is_red (&pb->geqs[e], desired_res)))
- {
- lower_bound = -c;
- l_color = pb->geqs[e].color;
- }
- }
- else
- {
- if (a != -1)
- c = int_div (c, -a);
- if (upper_bound > c
- || (upper_bound == c
- && !omega_eqn_is_red (&pb->geqs[e], desired_res)))
- {
- upper_bound = c;
- u_color = pb->geqs[e].color;
- }
- }
- }
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file, "upper bound = %d\n", upper_bound);
- fprintf (dump_file, "lower bound = %d\n", lower_bound);
- }
- if (lower_bound > upper_bound)
- return omega_problem_has_no_solution ();
- if (desired_res == omega_simplify)
- {
- pb->num_geqs = 0;
- if (pb->safe_vars == 1)
- {
- if (lower_bound == upper_bound
- && u_color == omega_black
- && l_color == omega_black)
- {
- pb->eqs[0].coef[0] = -lower_bound;
- pb->eqs[0].coef[1] = 1;
- pb->eqs[0].color = omega_black;
- pb->num_eqs = 1;
- return omega_solve_problem (pb, desired_res);
- }
- else
- {
- if (lower_bound > neg_infinity)
- {
- pb->geqs[0].coef[0] = -lower_bound;
- pb->geqs[0].coef[1] = 1;
- pb->geqs[0].key = 1;
- pb->geqs[0].color = l_color;
- pb->geqs[0].touched = 0;
- pb->num_geqs = 1;
- }
- if (upper_bound < pos_infinity)
- {
- pb->geqs[pb->num_geqs].coef[0] = upper_bound;
- pb->geqs[pb->num_geqs].coef[1] = -1;
- pb->geqs[pb->num_geqs].key = -1;
- pb->geqs[pb->num_geqs].color = u_color;
- pb->geqs[pb->num_geqs].touched = 0;
- pb->num_geqs++;
- }
- }
- }
- else
- pb->num_vars = 0;
- omega_problem_reduced (pb);
- return omega_false;
- }
- if (original_problem != no_problem
- && l_color == omega_black
- && u_color == omega_black
- && !conservative
- && lower_bound == upper_bound)
- {
- pb->eqs[0].coef[0] = -lower_bound;
- pb->eqs[0].coef[1] = 1;
- pb->num_eqs = 1;
- adding_equality_constraint (pb, 0);
- }
- return omega_true;
- }
- if (!pb->variables_freed)
- {
- pb->variables_freed = true;
- if (desired_res != omega_simplify)
- omega_free_eliminations (pb, 0);
- else
- omega_free_eliminations (pb, pb->safe_vars);
- n_vars = pb->num_vars;
- if (n_vars == 1)
- continue;
- }
- switch (normalize_omega_problem (pb))
- {
- case normalize_false:
- return omega_false;
- break;
- case normalize_coupled:
- coupled_subscripts = true;
- break;
- case normalize_uncoupled:
- coupled_subscripts = false;
- break;
- default:
- gcc_unreachable ();
- }
- n_vars = pb->num_vars;
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file, "\nafter normalization:\n");
- omega_print_problem (dump_file, pb);
- fprintf (dump_file, "\n");
- fprintf (dump_file, "eliminating variable using Fourier-Motzkin.\n");
- }
- do {
- int parallel_difference = INT_MAX;
- int best_parallel_eqn = -1;
- int minC, maxC, minCj = 0;
- int lower_bound_count = 0;
- int e2, Le = 0, Ue;
- bool possible_easy_int_solution;
- int max_splinters = 1;
- bool exact = false;
- bool lucky_exact = false;
- int best = (INT_MAX);
- int j = 0, jLe = 0, jLowerBoundCount = 0;
- eliminate_again = false;
- if (pb->num_eqs > 0)
- return omega_solve_problem (pb, desired_res);
- if (!coupled_subscripts)
- {
- if (pb->safe_vars == 0)
- pb->num_geqs = 0;
- else
- for (e = pb->num_geqs - 1; e >= 0; e--)
- if (!omega_safe_var_p (pb, abs (pb->geqs[e].key)))
- omega_delete_geq (pb, e, n_vars);
- pb->num_vars = pb->safe_vars;
- if (desired_res == omega_simplify)
- {
- omega_problem_reduced (pb);
- return omega_false;
- }
- return omega_true;
- }
- if (desired_res != omega_simplify)
- fv = 0;
- else
- fv = pb->safe_vars;
- if (pb->num_geqs == 0)
- {
- if (desired_res == omega_simplify)
- {
- pb->num_vars = pb->safe_vars;
- omega_problem_reduced (pb);
- return omega_false;
- }
- return omega_true;
- }
- if (desired_res == omega_simplify && n_vars == pb->safe_vars)
- {
- omega_problem_reduced (pb);
- return omega_false;
- }
- if (pb->num_geqs > OMEGA_MAX_GEQS - 30
- || pb->num_geqs > 2 * n_vars * n_vars + 4 * n_vars + 10)
- {
- if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file,
- "TOO MANY EQUATIONS; "
- "%d equations, %d variables, "
- "ELIMINATING REDUNDANT ONES\n",
- pb->num_geqs, n_vars);
- if (!omega_eliminate_redundant (pb, false))
- return omega_false;
- n_vars = pb->num_vars;
- if (pb->num_eqs > 0)
- return omega_solve_problem (pb, desired_res);
- if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file, "END ELIMINATION OF REDUNDANT EQUATIONS\n");
- }
- if (desired_res != omega_simplify)
- fv = 0;
- else
- fv = pb->safe_vars;
- for (i = n_vars; i != fv; i--)
- {
- int score;
- int ub = -2;
- int lb = -2;
- bool lucky = false;
- int upper_bound_count = 0;
- lower_bound_count = 0;
- minC = maxC = 0;
- for (e = pb->num_geqs - 1; e >= 0; e--)
- if (pb->geqs[e].coef[i] < 0)
- {
- minC = MIN (minC, pb->geqs[e].coef[i]);
- upper_bound_count++;
- if (pb->geqs[e].coef[i] < -1)
- {
- if (ub == -2)
- ub = e;
- else
- ub = -1;
- }
- }
- else if (pb->geqs[e].coef[i] > 0)
- {
- maxC = MAX (maxC, pb->geqs[e].coef[i]);
- lower_bound_count++;
- Le = e;
- if (pb->geqs[e].coef[i] > 1)
- {
- if (lb == -2)
- lb = e;
- else
- lb = -1;
- }
- }
- if (lower_bound_count == 0
- || upper_bound_count == 0)
- {
- lower_bound_count = 0;
- break;
- }
- if (ub >= 0 && lb >= 0
- && pb->geqs[lb].key == -pb->geqs[ub].key)
- {
- int Lc = pb->geqs[lb].coef[i];
- int Uc = -pb->geqs[ub].coef[i];
- int diff =
- Lc * pb->geqs[ub].coef[0] + Uc * pb->geqs[lb].coef[0];
- lucky = (diff >= (Uc - 1) * (Lc - 1));
- }
- if (maxC == 1
- || minC == -1
- || lucky
- || in_approximate_mode)
- {
- score = upper_bound_count * lower_bound_count;
- if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file,
- "For %s, exact, score = %d*%d, range = %d ... %d,"
- "\nlucky = %d, in_approximate_mode=%d \n",
- omega_variable_to_str (pb, i),
- upper_bound_count,
- lower_bound_count, minC, maxC, lucky,
- in_approximate_mode);
- if (!exact
- || score < best)
- {
- best = score;
- j = i;
- minCj = minC;
- jLe = Le;
- jLowerBoundCount = lower_bound_count;
- exact = true;
- lucky_exact = lucky;
- if (score == 1)
- break;
- }
- }
- else if (!exact)
- {
- if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file,
- "For %s, non-exact, score = %d*%d,"
- "range = %d ... %d \n",
- omega_variable_to_str (pb, i),
- upper_bound_count,
- lower_bound_count, minC, maxC);
- score = maxC - minC;
- if (best > score)
- {
- best = score;
- j = i;
- minCj = minC;
- jLe = Le;
- jLowerBoundCount = lower_bound_count;
- }
- }
- }
- if (lower_bound_count == 0)
- {
- omega_free_eliminations (pb, pb->safe_vars);
- n_vars = pb->num_vars;
- eliminate_again = true;
- continue;
- }
- i = j;
- minC = minCj;
- Le = jLe;
- lower_bound_count = jLowerBoundCount;
- for (e = pb->num_geqs - 1; e >= 0; e--)
- if (pb->geqs[e].coef[i] > 0)
- {
- if (pb->geqs[e].coef[i] == -minC)
- max_splinters += -minC - 1;
- else
- max_splinters +=
- pos_mul_hwi ((pb->geqs[e].coef[i] - 1),
- (-minC - 1)) / (-minC) + 1;
- }
- /* #ifdef Omega3 */
- /* Trying to produce exact elimination by finding redundant
- constraints. */
- if (!exact && !tried_eliminating_redundant)
- {
- omega_eliminate_redundant (pb, false);
- tried_eliminating_redundant = true;
- eliminate_again = true;
- continue;
- }
- tried_eliminating_redundant = false;
- /* #endif */
- if (return_single_result && desired_res == omega_simplify && !exact)
- {
- omega_problem_reduced (pb);
- return omega_true;
- }
- /* #ifndef Omega3 */
- /* Trying to produce exact elimination by finding redundant
- constraints. */
- if (!exact && !tried_eliminating_redundant)
- {
- omega_eliminate_redundant (pb, false);
- tried_eliminating_redundant = true;
- continue;
- }
- tried_eliminating_redundant = false;
- /* #endif */
- if (!exact)
- {
- int e1, e2;
- for (e1 = pb->num_geqs - 1; e1 >= 0; e1--)
- if (pb->geqs[e1].color == omega_black)
- for (e2 = e1 - 1; e2 >= 0; e2--)
- if (pb->geqs[e2].color == omega_black
- && pb->geqs[e1].key == -pb->geqs[e2].key
- && ((pb->geqs[e1].coef[0] + pb->geqs[e2].coef[0])
- * (3 - single_var_geq (&pb->geqs[e1], pb->num_vars))
- / 2 < parallel_difference))
- {
- parallel_difference =
- (pb->geqs[e1].coef[0] + pb->geqs[e2].coef[0])
- * (3 - single_var_geq (&pb->geqs[e1], pb->num_vars))
- / 2;
- best_parallel_eqn = e1;
- }
- if (dump_file && (dump_flags & TDF_DETAILS)
- && best_parallel_eqn >= 0)
- {
- fprintf (dump_file,
- "Possible parallel projection, diff = %d, in ",
- parallel_difference);
- omega_print_geq (dump_file, pb, &(pb->geqs[best_parallel_eqn]));
- fprintf (dump_file, "\n");
- omega_print_problem (dump_file, pb);
- }
- }
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file, "going to eliminate %s, (%d,%d,%d)\n",
- omega_variable_to_str (pb, i), i, minC,
- lower_bound_count);
- omega_print_problem (dump_file, pb);
- if (lucky_exact)
- fprintf (dump_file, "(a lucky exact elimination)\n");
- else if (exact)
- fprintf (dump_file, "(an exact elimination)\n");
- fprintf (dump_file, "Max # of splinters = %d\n", max_splinters);
- }
- gcc_assert (max_splinters >= 1);
- if (!exact && desired_res == omega_simplify && best_parallel_eqn >= 0
- && parallel_difference <= max_splinters)
- return parallel_splinter (pb, best_parallel_eqn, parallel_difference,
- desired_res);
- smoothed = false;
- if (i != n_vars)
- {
- int t;
- int j = pb->num_vars;
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file, "Swapping %d and %d\n", i, j);
- omega_print_problem (dump_file, pb);
- }
- swap (&pb->var[i], &pb->var[j]);
- for (e = pb->num_geqs - 1; e >= 0; e--)
- if (pb->geqs[e].coef[i] != pb->geqs[e].coef[j])
- {
- pb->geqs[e].touched = 1;
- t = pb->geqs[e].coef[i];
- pb->geqs[e].coef[i] = pb->geqs[e].coef[j];
- pb->geqs[e].coef[j] = t;
- }
- for (e = pb->num_subs - 1; e >= 0; e--)
- if (pb->subs[e].coef[i] != pb->subs[e].coef[j])
- {
- t = pb->subs[e].coef[i];
- pb->subs[e].coef[i] = pb->subs[e].coef[j];
- pb->subs[e].coef[j] = t;
- }
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file, "Swapping complete \n");
- omega_print_problem (dump_file, pb);
- fprintf (dump_file, "\n");
- }
- i = j;
- }
- else if (dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file, "No swap needed\n");
- omega_print_problem (dump_file, pb);
- }
- pb->num_vars--;
- n_vars = pb->num_vars;
- if (exact)
- {
- if (n_vars == 1)
- {
- int upper_bound = pos_infinity;
- int lower_bound = neg_infinity;
- enum omega_eqn_color ub_color = omega_black;
- enum omega_eqn_color lb_color = omega_black;
- int topeqn = pb->num_geqs - 1;
- int Lc = pb->geqs[Le].coef[i];
- for (Le = topeqn; Le >= 0; Le--)
- if ((Lc = pb->geqs[Le].coef[i]) == 0)
- {
- if (pb->geqs[Le].coef[1] == 1)
- {
- int constantTerm = -pb->geqs[Le].coef[0];
- if (constantTerm > lower_bound ||
- (constantTerm == lower_bound &&
- !omega_eqn_is_red (&pb->geqs[Le], desired_res)))
- {
- lower_bound = constantTerm;
- lb_color = pb->geqs[Le].color;
- }
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- if (pb->geqs[Le].color == omega_black)
- fprintf (dump_file, " :::=> %s >= %d\n",
- omega_variable_to_str (pb, 1),
- constantTerm);
- else
- fprintf (dump_file,
- " :::=> [%s >= %d]\n",
- omega_variable_to_str (pb, 1),
- constantTerm);
- }
- }
- else
- {
- int constantTerm = pb->geqs[Le].coef[0];
- if (constantTerm < upper_bound ||
- (constantTerm == upper_bound
- && !omega_eqn_is_red (&pb->geqs[Le],
- desired_res)))
- {
- upper_bound = constantTerm;
- ub_color = pb->geqs[Le].color;
- }
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- if (pb->geqs[Le].color == omega_black)
- fprintf (dump_file, " :::=> %s <= %d\n",
- omega_variable_to_str (pb, 1),
- constantTerm);
- else
- fprintf (dump_file,
- " :::=> [%s <= %d]\n",
- omega_variable_to_str (pb, 1),
- constantTerm);
- }
- }
- }
- else if (Lc > 0)
- for (Ue = topeqn; Ue >= 0; Ue--)
- if (pb->geqs[Ue].coef[i] < 0
- && pb->geqs[Le].key != -pb->geqs[Ue].key)
- {
- int Uc = -pb->geqs[Ue].coef[i];
- int coefficient = pb->geqs[Ue].coef[1] * Lc
- + pb->geqs[Le].coef[1] * Uc;
- int constantTerm = pb->geqs[Ue].coef[0] * Lc
- + pb->geqs[Le].coef[0] * Uc;
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- omega_print_geq_extra (dump_file, pb,
- &(pb->geqs[Ue]));
- fprintf (dump_file, "\n");
- omega_print_geq_extra (dump_file, pb,
- &(pb->geqs[Le]));
- fprintf (dump_file, "\n");
- }
- if (coefficient > 0)
- {
- constantTerm = -int_div (constantTerm, coefficient);
- if (constantTerm > lower_bound
- || (constantTerm == lower_bound
- && (desired_res != omega_simplify
- || (pb->geqs[Ue].color == omega_black
- && pb->geqs[Le].color == omega_black))))
- {
- lower_bound = constantTerm;
- lb_color = (pb->geqs[Ue].color == omega_red
- || pb->geqs[Le].color == omega_red)
- ? omega_red : omega_black;
- }
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- if (pb->geqs[Ue].color == omega_red
- || pb->geqs[Le].color == omega_red)
- fprintf (dump_file,
- " ::=> [%s >= %d]\n",
- omega_variable_to_str (pb, 1),
- constantTerm);
- else
- fprintf (dump_file,
- " ::=> %s >= %d\n",
- omega_variable_to_str (pb, 1),
- constantTerm);
- }
- }
- else
- {
- constantTerm = int_div (constantTerm, -coefficient);
- if (constantTerm < upper_bound
- || (constantTerm == upper_bound
- && pb->geqs[Ue].color == omega_black
- && pb->geqs[Le].color == omega_black))
- {
- upper_bound = constantTerm;
- ub_color = (pb->geqs[Ue].color == omega_red
- || pb->geqs[Le].color == omega_red)
- ? omega_red : omega_black;
- }
- if (dump_file
- && (dump_flags & TDF_DETAILS))
- {
- if (pb->geqs[Ue].color == omega_red
- || pb->geqs[Le].color == omega_red)
- fprintf (dump_file,
- " ::=> [%s <= %d]\n",
- omega_variable_to_str (pb, 1),
- constantTerm);
- else
- fprintf (dump_file,
- " ::=> %s <= %d\n",
- omega_variable_to_str (pb, 1),
- constantTerm);
- }
- }
- }
- pb->num_geqs = 0;
- if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file,
- " therefore, %c%d <= %c%s%c <= %d%c\n",
- lb_color == omega_red ? '[' : ' ', lower_bound,
- (lb_color == omega_red && ub_color == omega_black)
- ? ']' : ' ',
- omega_variable_to_str (pb, 1),
- (lb_color == omega_black && ub_color == omega_red)
- ? '[' : ' ',
- upper_bound, ub_color == omega_red ? ']' : ' ');
- if (lower_bound > upper_bound)
- return omega_false;
- if (pb->safe_vars == 1)
- {
- if (upper_bound == lower_bound
- && !(ub_color == omega_red || lb_color == omega_red)
- && !please_no_equalities_in_simplified_problems)
- {
- pb->num_eqs++;
- pb->eqs[0].coef[1] = -1;
- pb->eqs[0].coef[0] = upper_bound;
- if (ub_color == omega_red
- || lb_color == omega_red)
- pb->eqs[0].color = omega_red;
- if (desired_res == omega_simplify
- && pb->eqs[0].color == omega_black)
- return omega_solve_problem (pb, desired_res);
- }
- if (upper_bound != pos_infinity)
- {
- pb->geqs[0].coef[1] = -1;
- pb->geqs[0].coef[0] = upper_bound;
- pb->geqs[0].color = ub_color;
- pb->geqs[0].key = -1;
- pb->geqs[0].touched = 0;
- pb->num_geqs++;
- }
- if (lower_bound != neg_infinity)
- {
- pb->geqs[pb->num_geqs].coef[1] = 1;
- pb->geqs[pb->num_geqs].coef[0] = -lower_bound;
- pb->geqs[pb->num_geqs].color = lb_color;
- pb->geqs[pb->num_geqs].key = 1;
- pb->geqs[pb->num_geqs].touched = 0;
- pb->num_geqs++;
- }
- }
- if (desired_res == omega_simplify)
- {
- omega_problem_reduced (pb);
- return omega_false;
- }
- else
- {
- if (!conservative
- && (desired_res != omega_simplify
- || (lb_color == omega_black
- && ub_color == omega_black))
- && original_problem != no_problem
- && lower_bound == upper_bound)
- {
- for (i = original_problem->num_vars; i >= 0; i--)
- if (original_problem->var[i] == pb->var[1])
- break;
- if (i == 0)
- break;
- e = original_problem->num_eqs++;
- omega_init_eqn_zero (&original_problem->eqs[e],
- original_problem->num_vars);
- original_problem->eqs[e].coef[i] = -1;
- original_problem->eqs[e].coef[0] = upper_bound;
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file,
- "adding equality %d to outer problem\n", e);
- omega_print_problem (dump_file, original_problem);
- }
- }
- return omega_true;
- }
- }
- eliminate_again = true;
- if (lower_bound_count == 1)
- {
- eqn lbeqn = omega_alloc_eqns (0, 1);
- int Lc = pb->geqs[Le].coef[i];
- if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file, "an inplace elimination\n");
- omega_copy_eqn (lbeqn, &pb->geqs[Le], (n_vars + 1));
- omega_delete_geq_extra (pb, Le, n_vars + 1);
- for (Ue = pb->num_geqs - 1; Ue >= 0; Ue--)
- if (pb->geqs[Ue].coef[i] < 0)
- {
- if (lbeqn->key == -pb->geqs[Ue].key)
- omega_delete_geq_extra (pb, Ue, n_vars + 1);
- else
- {
- int k;
- int Uc = -pb->geqs[Ue].coef[i];
- pb->geqs[Ue].touched = 1;
- eliminate_again = false;
- if (lbeqn->color == omega_red)
- pb->geqs[Ue].color = omega_red;
- for (k = 0; k <= n_vars; k++)
- pb->geqs[Ue].coef[k] =
- mul_hwi (pb->geqs[Ue].coef[k], Lc) +
- mul_hwi (lbeqn->coef[k], Uc);
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- omega_print_geq (dump_file, pb,
- &(pb->geqs[Ue]));
- fprintf (dump_file, "\n");
- }
- }
- }
- omega_free_eqns (lbeqn, 1);
- continue;
- }
- else
- {
- int *dead_eqns = XNEWVEC (int, OMEGA_MAX_GEQS);
- bool *is_dead = XNEWVEC (bool, OMEGA_MAX_GEQS);
- int num_dead = 0;
- int top_eqn = pb->num_geqs - 1;
- lower_bound_count--;
- if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file, "lower bound count = %d\n",
- lower_bound_count);
- for (Le = top_eqn; Le >= 0; Le--)
- if (pb->geqs[Le].coef[i] > 0)
- {
- int Lc = pb->geqs[Le].coef[i];
- for (Ue = top_eqn; Ue >= 0; Ue--)
- if (pb->geqs[Ue].coef[i] < 0)
- {
- if (pb->geqs[Le].key != -pb->geqs[Ue].key)
- {
- int k;
- int Uc = -pb->geqs[Ue].coef[i];
- if (num_dead == 0)
- e2 = pb->num_geqs++;
- else
- e2 = dead_eqns[--num_dead];
- gcc_assert (e2 < OMEGA_MAX_GEQS);
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file,
- "Le = %d, Ue = %d, gen = %d\n",
- Le, Ue, e2);
- omega_print_geq_extra (dump_file, pb,
- &(pb->geqs[Le]));
- fprintf (dump_file, "\n");
- omega_print_geq_extra (dump_file, pb,
- &(pb->geqs[Ue]));
- fprintf (dump_file, "\n");
- }
- eliminate_again = false;
- for (k = n_vars; k >= 0; k--)
- pb->geqs[e2].coef[k] =
- mul_hwi (pb->geqs[Ue].coef[k], Lc) +
- mul_hwi (pb->geqs[Le].coef[k], Uc);
- pb->geqs[e2].coef[n_vars + 1] = 0;
- pb->geqs[e2].touched = 1;
- if (pb->geqs[Ue].color == omega_red
- || pb->geqs[Le].color == omega_red)
- pb->geqs[e2].color = omega_red;
- else
- pb->geqs[e2].color = omega_black;
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- omega_print_geq (dump_file, pb,
- &(pb->geqs[e2]));
- fprintf (dump_file, "\n");
- }
- }
- if (lower_bound_count == 0)
- {
- dead_eqns[num_dead++] = Ue;
- if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file, "Killed %d\n", Ue);
- }
- }
- lower_bound_count--;
- dead_eqns[num_dead++] = Le;
- if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file, "Killed %d\n", Le);
- }
- for (e = pb->num_geqs - 1; e >= 0; e--)
- is_dead[e] = false;
- while (num_dead > 0)
- is_dead[dead_eqns[--num_dead]] = true;
- for (e = pb->num_geqs - 1; e >= 0; e--)
- if (is_dead[e])
- omega_delete_geq_extra (pb, e, n_vars + 1);
- free (dead_eqns);
- free (is_dead);
- continue;
- }
- }
- else
- {
- omega_pb rS, iS;
- rS = omega_alloc_problem (0, 0);
- iS = omega_alloc_problem (0, 0);
- e2 = 0;
- possible_easy_int_solution = true;
- for (e = 0; e < pb->num_geqs; e++)
- if (pb->geqs[e].coef[i] == 0)
- {
- omega_copy_eqn (&(rS->geqs[e2]), &pb->geqs[e],
- pb->num_vars);
- omega_copy_eqn (&(iS->geqs[e2]), &pb->geqs[e],
- pb->num_vars);
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- int t;
- fprintf (dump_file, "Copying (%d, %d): ", i,
- pb->geqs[e].coef[i]);
- omega_print_geq_extra (dump_file, pb, &pb->geqs[e]);
- fprintf (dump_file, "\n");
- for (t = 0; t <= n_vars + 1; t++)
- fprintf (dump_file, "%d ", pb->geqs[e].coef[t]);
- fprintf (dump_file, "\n");
- }
- e2++;
- gcc_assert (e2 < OMEGA_MAX_GEQS);
- }
- for (Le = pb->num_geqs - 1; Le >= 0; Le--)
- if (pb->geqs[Le].coef[i] > 0)
- for (Ue = pb->num_geqs - 1; Ue >= 0; Ue--)
- if (pb->geqs[Ue].coef[i] < 0)
- {
- int k;
- int Lc = pb->geqs[Le].coef[i];
- int Uc = -pb->geqs[Ue].coef[i];
- if (pb->geqs[Le].key != -pb->geqs[Ue].key)
- {
- rS->geqs[e2].touched = iS->geqs[e2].touched = 1;
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file, "---\n");
- fprintf (dump_file,
- "Le(Lc) = %d(%d_, Ue(Uc) = %d(%d), gen = %d\n",
- Le, Lc, Ue, Uc, e2);
- omega_print_geq_extra (dump_file, pb, &pb->geqs[Le]);
- fprintf (dump_file, "\n");
- omega_print_geq_extra (dump_file, pb, &pb->geqs[Ue]);
- fprintf (dump_file, "\n");
- }
- if (Uc == Lc)
- {
- for (k = n_vars; k >= 0; k--)
- iS->geqs[e2].coef[k] = rS->geqs[e2].coef[k] =
- pb->geqs[Ue].coef[k] + pb->geqs[Le].coef[k];
- iS->geqs[e2].coef[0] -= (Uc - 1);
- }
- else
- {
- for (k = n_vars; k >= 0; k--)
- iS->geqs[e2].coef[k] = rS->geqs[e2].coef[k] =
- mul_hwi (pb->geqs[Ue].coef[k], Lc) +
- mul_hwi (pb->geqs[Le].coef[k], Uc);
- iS->geqs[e2].coef[0] -= (Uc - 1) * (Lc - 1);
- }
- if (pb->geqs[Ue].color == omega_red
- || pb->geqs[Le].color == omega_red)
- iS->geqs[e2].color = rS->geqs[e2].color = omega_red;
- else
- iS->geqs[e2].color = rS->geqs[e2].color = omega_black;
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- omega_print_geq (dump_file, pb, &(rS->geqs[e2]));
- fprintf (dump_file, "\n");
- }
- e2++;
- gcc_assert (e2 < OMEGA_MAX_GEQS);
- }
- else if (pb->geqs[Ue].coef[0] * Lc +
- pb->geqs[Le].coef[0] * Uc -
- (Uc - 1) * (Lc - 1) < 0)
- possible_easy_int_solution = false;
- }
- iS->variables_initialized = rS->variables_initialized = true;
- iS->num_vars = rS->num_vars = pb->num_vars;
- iS->num_geqs = rS->num_geqs = e2;
- iS->num_eqs = rS->num_eqs = 0;
- iS->num_subs = rS->num_subs = pb->num_subs;
- iS->safe_vars = rS->safe_vars = pb->safe_vars;
- for (e = n_vars; e >= 0; e--)
- rS->var[e] = pb->var[e];
- for (e = n_vars; e >= 0; e--)
- iS->var[e] = pb->var[e];
- for (e = pb->num_subs - 1; e >= 0; e--)
- {
- omega_copy_eqn (&(rS->subs[e]), &(pb->subs[e]), pb->num_vars);
- omega_copy_eqn (&(iS->subs[e]), &(pb->subs[e]), pb->num_vars);
- }
- pb->num_vars++;
- n_vars = pb->num_vars;
- if (desired_res != omega_true)
- {
- if (original_problem == no_problem)
- {
- original_problem = pb;
- result = omega_solve_geq (rS, omega_false);
- original_problem = no_problem;
- }
- else
- result = omega_solve_geq (rS, omega_false);
- if (result == omega_false)
- {
- free (rS);
- free (iS);
- return result;
- }
- if (pb->num_eqs > 0)
- {
- /* An equality constraint must have been found */
- free (rS);
- free (iS);
- return omega_solve_problem (pb, desired_res);
- }
- }
- if (desired_res != omega_false)
- {
- int j;
- int lower_bounds = 0;
- int *lower_bound = XNEWVEC (int, OMEGA_MAX_GEQS);
- if (possible_easy_int_solution)
- {
- conservative++;
- result = omega_solve_geq (iS, desired_res);
- conservative--;
- if (result != omega_false)
- {
- free (rS);
- free (iS);
- free (lower_bound);
- return result;
- }
- }
- if (!exact && best_parallel_eqn >= 0
- && parallel_difference <= max_splinters)
- {
- free (rS);
- free (iS);
- free (lower_bound);
- return parallel_splinter (pb, best_parallel_eqn,
- parallel_difference,
- desired_res);
- }
- if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file, "have to do exact analysis\n");
- conservative++;
- for (e = 0; e < pb->num_geqs; e++)
- if (pb->geqs[e].coef[i] > 1)
- lower_bound[lower_bounds++] = e;
- /* Sort array LOWER_BOUND. */
- for (j = 0; j < lower_bounds; j++)
- {
- int k, smallest = j;
- for (k = j + 1; k < lower_bounds; k++)
- if (pb->geqs[lower_bound[smallest]].coef[i] >
- pb->geqs[lower_bound[k]].coef[i])
- smallest = k;
- k = lower_bound[smallest];
- lower_bound[smallest] = lower_bound[j];
- lower_bound[j] = k;
- }
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file, "lower bound coefficients = ");
- for (j = 0; j < lower_bounds; j++)
- fprintf (dump_file, " %d",
- pb->geqs[lower_bound[j]].coef[i]);
- fprintf (dump_file, "\n");
- }
- for (j = 0; j < lower_bounds; j++)
- {
- int max_incr;
- int c;
- int worst_lower_bound_constant = -minC;
- e = lower_bound[j];
- max_incr = (((pb->geqs[e].coef[i] - 1) *
- (worst_lower_bound_constant - 1) - 1)
- / worst_lower_bound_constant);
- /* max_incr += 2; */
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file, "for equation ");
- omega_print_geq (dump_file, pb, &pb->geqs[e]);
- fprintf (dump_file,
- "\ntry decrements from 0 to %d\n",
- max_incr);
- omega_print_problem (dump_file, pb);
- }
- if (max_incr > 50 && !smoothed
- && smooth_weird_equations (pb))
- {
- conservative--;
- free (rS);
- free (iS);
- smoothed = true;
- goto solve_geq_start;
- }
- omega_copy_eqn (&pb->eqs[0], &pb->geqs[e],
- pb->num_vars);
- pb->eqs[0].color = omega_black;
- omega_init_eqn_zero (&pb->geqs[e], pb->num_vars);
- pb->geqs[e].touched = 1;
- pb->num_eqs = 1;
- for (c = max_incr; c >= 0; c--)
- {
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file,
- "trying next decrement of %d\n",
- max_incr - c);
- omega_print_problem (dump_file, pb);
- }
- omega_copy_problem (rS, pb);
- if (dump_file && (dump_flags & TDF_DETAILS))
- omega_print_problem (dump_file, rS);
- result = omega_solve_problem (rS, desired_res);
- if (result == omega_true)
- {
- free (rS);
- free (iS);
- free (lower_bound);
- conservative--;
- return omega_true;
- }
- pb->eqs[0].coef[0]--;
- }
- if (j + 1 < lower_bounds)
- {
- pb->num_eqs = 0;
- omega_copy_eqn (&pb->geqs[e], &pb->eqs[0],
- pb->num_vars);
- pb->geqs[e].touched = 1;
- pb->geqs[e].color = omega_black;
- omega_copy_problem (rS, pb);
- if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file,
- "exhausted lower bound, "
- "checking if still feasible ");
- result = omega_solve_problem (rS, omega_false);
- if (result == omega_false)
- break;
- }
- }
- if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file, "fall-off the end\n");
- free (rS);
- free (iS);
- free (lower_bound);
- conservative--;
- return omega_false;
- }
- free (rS);
- free (iS);
- }
- return omega_unknown;
- } while (eliminate_again);
- } while (1);
- }
- /* Because the omega solver is recursive, this counter limits the
- recursion depth. */
- static int omega_solve_depth = 0;
- /* Return omega_true when the problem PB has a solution following the
- DESIRED_RES. */
- enum omega_result
- omega_solve_problem (omega_pb pb, enum omega_result desired_res)
- {
- enum omega_result result;
- gcc_assert (pb->num_vars >= pb->safe_vars);
- omega_solve_depth++;
- if (desired_res != omega_simplify)
- pb->safe_vars = 0;
- if (omega_solve_depth > 50)
- {
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file,
- "Solve depth = %d, in_approximate_mode = %d, aborting\n",
- omega_solve_depth, in_approximate_mode);
- omega_print_problem (dump_file, pb);
- }
- gcc_assert (0);
- }
- if (omega_solve_eq (pb, desired_res) == omega_false)
- {
- omega_solve_depth--;
- return omega_false;
- }
- if (in_approximate_mode && !pb->num_geqs)
- {
- result = omega_true;
- pb->num_vars = pb->safe_vars;
- omega_problem_reduced (pb);
- }
- else
- result = omega_solve_geq (pb, desired_res);
- omega_solve_depth--;
- if (!omega_reduce_with_subs)
- {
- resurrect_subs (pb);
- gcc_assert (please_no_equalities_in_simplified_problems
- || !result || pb->num_subs == 0);
- }
- return result;
- }
- /* Return true if red equations constrain the set of possible solutions.
- We assume that there are solutions to the black equations by
- themselves, so if there is no solution to the combined problem, we
- return true. */
- bool
- omega_problem_has_red_equations (omega_pb pb)
- {
- bool result;
- int e;
- int i;
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file, "Checking for red equations:\n");
- omega_print_problem (dump_file, pb);
- }
- please_no_equalities_in_simplified_problems++;
- may_be_red++;
- if (omega_single_result)
- return_single_result++;
- create_color = true;
- result = (omega_simplify_problem (pb) == omega_false);
- if (omega_single_result)
- return_single_result--;
- may_be_red--;
- please_no_equalities_in_simplified_problems--;
- if (result)
- {
- if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file, "Gist is FALSE\n");
- pb->num_subs = 0;
- pb->num_geqs = 0;
- pb->num_eqs = 1;
- pb->eqs[0].color = omega_red;
- for (i = pb->num_vars; i > 0; i--)
- pb->eqs[0].coef[i] = 0;
- pb->eqs[0].coef[0] = 1;
- return true;
- }
- free_red_eliminations (pb);
- gcc_assert (pb->num_eqs == 0);
- for (e = pb->num_geqs - 1; e >= 0; e--)
- if (pb->geqs[e].color == omega_red)
- {
- result = true;
- break;
- }
- if (!result)
- return false;
- for (i = pb->safe_vars; i >= 1; i--)
- {
- int ub = 0;
- int lb = 0;
- for (e = pb->num_geqs - 1; e >= 0; e--)
- {
- if (pb->geqs[e].coef[i])
- {
- if (pb->geqs[e].coef[i] > 0)
- lb |= (1 + (pb->geqs[e].color == omega_red ? 1 : 0));
- else
- ub |= (1 + (pb->geqs[e].color == omega_red ? 1 : 0));
- }
- }
- if (ub == 2 || lb == 2)
- {
- if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file, "checks for upper/lower bounds worked!\n");
- if (!omega_reduce_with_subs)
- {
- resurrect_subs (pb);
- gcc_assert (pb->num_subs == 0);
- }
- return true;
- }
- }
- if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file,
- "*** Doing potentially expensive elimination tests "
- "for red equations\n");
- please_no_equalities_in_simplified_problems++;
- omega_eliminate_red (pb, true);
- please_no_equalities_in_simplified_problems--;
- result = false;
- gcc_assert (pb->num_eqs == 0);
- for (e = pb->num_geqs - 1; e >= 0; e--)
- if (pb->geqs[e].color == omega_red)
- {
- result = true;
- break;
- }
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- if (!result)
- fprintf (dump_file,
- "******************** Redundant Red Equations eliminated!!\n");
- else
- fprintf (dump_file,
- "******************** Red Equations remain\n");
- omega_print_problem (dump_file, pb);
- }
- if (!omega_reduce_with_subs)
- {
- normalize_return_type r;
- resurrect_subs (pb);
- r = normalize_omega_problem (pb);
- gcc_assert (r != normalize_false);
- coalesce (pb);
- cleanout_wildcards (pb);
- gcc_assert (pb->num_subs == 0);
- }
- return result;
- }
- /* Calls omega_simplify_problem in approximate mode. */
- enum omega_result
- omega_simplify_approximate (omega_pb pb)
- {
- enum omega_result result;
- if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file, "(Entering approximate mode\n");
- in_approximate_mode = true;
- result = omega_simplify_problem (pb);
- in_approximate_mode = false;
- gcc_assert (pb->num_vars == pb->safe_vars);
- if (!omega_reduce_with_subs)
- gcc_assert (pb->num_subs == 0);
- if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file, "Leaving approximate mode)\n");
- return result;
- }
- /* Simplifies problem PB by eliminating redundant constraints and
- reducing the constraints system to a minimal form. Returns
- omega_true when the problem was successfully reduced, omega_unknown
- when the solver is unable to determine an answer. */
- enum omega_result
- omega_simplify_problem (omega_pb pb)
- {
- int i;
- omega_found_reduction = omega_false;
- if (!pb->variables_initialized)
- omega_initialize_variables (pb);
- if (next_key * 3 > MAX_KEYS)
- {
- int e;
- hash_version++;
- next_key = OMEGA_MAX_VARS + 1;
- for (e = pb->num_geqs - 1; e >= 0; e--)
- pb->geqs[e].touched = 1;
- for (i = 0; i < HASH_TABLE_SIZE; i++)
- hash_master[i].touched = -1;
- pb->hash_version = hash_version;
- }
- else if (pb->hash_version != hash_version)
- {
- int e;
- for (e = pb->num_geqs - 1; e >= 0; e--)
- pb->geqs[e].touched = 1;
- pb->hash_version = hash_version;
- }
- if (pb->num_vars > pb->num_eqs + 3 * pb->safe_vars)
- omega_free_eliminations (pb, pb->safe_vars);
- if (!may_be_red && pb->num_subs == 0 && pb->safe_vars == 0)
- {
- omega_found_reduction = omega_solve_problem (pb, omega_unknown);
- if (omega_found_reduction != omega_false
- && !return_single_result)
- {
- pb->num_geqs = 0;
- pb->num_eqs = 0;
- (*omega_when_reduced) (pb);
- }
- return omega_found_reduction;
- }
- omega_solve_problem (pb, omega_simplify);
- if (omega_found_reduction != omega_false)
- {
- for (i = 1; omega_safe_var_p (pb, i); i++)
- pb->forwarding_address[pb->var[i]] = i;
- for (i = 0; i < pb->num_subs; i++)
- pb->forwarding_address[pb->subs[i].key] = -i - 1;
- }
- if (!omega_reduce_with_subs)
- gcc_assert (please_no_equalities_in_simplified_problems
- || omega_found_reduction == omega_false
- || pb->num_subs == 0);
- return omega_found_reduction;
- }
- /* Make variable VAR unprotected: it then can be eliminated. */
- void
- omega_unprotect_variable (omega_pb pb, int var)
- {
- int e, idx;
- idx = pb->forwarding_address[var];
- if (idx < 0)
- {
- idx = -1 - idx;
- pb->num_subs--;
- if (idx < pb->num_subs)
- {
- omega_copy_eqn (&pb->subs[idx], &pb->subs[pb->num_subs],
- pb->num_vars);
- pb->forwarding_address[pb->subs[idx].key] = -idx - 1;
- }
- }
- else
- {
- int *bring_to_life = XNEWVEC (int, OMEGA_MAX_VARS);
- int e2;
- for (e = pb->num_subs - 1; e >= 0; e--)
- bring_to_life[e] = (pb->subs[e].coef[idx] != 0);
- for (e2 = pb->num_subs - 1; e2 >= 0; e2--)
- if (bring_to_life[e2])
- {
- pb->num_vars++;
- pb->safe_vars++;
- if (pb->safe_vars < pb->num_vars)
- {
- for (e = pb->num_geqs - 1; e >= 0; e--)
- {
- pb->geqs[e].coef[pb->num_vars] =
- pb->geqs[e].coef[pb->safe_vars];
- pb->geqs[e].coef[pb->safe_vars] = 0;
- }
- for (e = pb->num_eqs - 1; e >= 0; e--)
- {
- pb->eqs[e].coef[pb->num_vars] =
- pb->eqs[e].coef[pb->safe_vars];
- pb->eqs[e].coef[pb->safe_vars] = 0;
- }
- for (e = pb->num_subs - 1; e >= 0; e--)
- {
- pb->subs[e].coef[pb->num_vars] =
- pb->subs[e].coef[pb->safe_vars];
- pb->subs[e].coef[pb->safe_vars] = 0;
- }
- pb->var[pb->num_vars] = pb->var[pb->safe_vars];
- pb->forwarding_address[pb->var[pb->num_vars]] =
- pb->num_vars;
- }
- else
- {
- for (e = pb->num_geqs - 1; e >= 0; e--)
- pb->geqs[e].coef[pb->safe_vars] = 0;
- for (e = pb->num_eqs - 1; e >= 0; e--)
- pb->eqs[e].coef[pb->safe_vars] = 0;
- for (e = pb->num_subs - 1; e >= 0; e--)
- pb->subs[e].coef[pb->safe_vars] = 0;
- }
- pb->var[pb->safe_vars] = pb->subs[e2].key;
- pb->forwarding_address[pb->subs[e2].key] = pb->safe_vars;
- omega_copy_eqn (&(pb->eqs[pb->num_eqs]), &(pb->subs[e2]),
- pb->num_vars);
- pb->eqs[pb->num_eqs++].coef[pb->safe_vars] = -1;
- gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
- if (e2 < pb->num_subs - 1)
- omega_copy_eqn (&(pb->subs[e2]), &(pb->subs[pb->num_subs - 1]),
- pb->num_vars);
- pb->num_subs--;
- }
- omega_unprotect_1 (pb, &idx, NULL);
- free (bring_to_life);
- }
- chain_unprotect (pb);
- }
- /* Unprotects VAR and simplifies PB. */
- enum omega_result
- omega_constrain_variable_sign (omega_pb pb, enum omega_eqn_color color,
- int var, int sign)
- {
- int n_vars = pb->num_vars;
- int e, j;
- int k = pb->forwarding_address[var];
- if (k < 0)
- {
- k = -1 - k;
- if (sign != 0)
- {
- e = pb->num_geqs++;
- omega_copy_eqn (&pb->geqs[e], &pb->subs[k], pb->num_vars);
- for (j = 0; j <= n_vars; j++)
- pb->geqs[e].coef[j] *= sign;
- pb->geqs[e].coef[0]--;
- pb->geqs[e].touched = 1;
- pb->geqs[e].color = color;
- }
- else
- {
- e = pb->num_eqs++;
- gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
- omega_copy_eqn (&pb->eqs[e], &pb->subs[k], pb->num_vars);
- pb->eqs[e].color = color;
- }
- }
- else if (sign != 0)
- {
- e = pb->num_geqs++;
- omega_init_eqn_zero (&pb->geqs[e], pb->num_vars);
- pb->geqs[e].coef[k] = sign;
- pb->geqs[e].coef[0] = -1;
- pb->geqs[e].touched = 1;
- pb->geqs[e].color = color;
- }
- else
- {
- e = pb->num_eqs++;
- gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
- omega_init_eqn_zero (&pb->eqs[e], pb->num_vars);
- pb->eqs[e].coef[k] = 1;
- pb->eqs[e].color = color;
- }
- omega_unprotect_variable (pb, var);
- return omega_simplify_problem (pb);
- }
- /* Add an equation "VAR = VALUE" with COLOR to PB. */
- void
- omega_constrain_variable_value (omega_pb pb, enum omega_eqn_color color,
- int var, int value)
- {
- int e;
- int k = pb->forwarding_address[var];
- if (k < 0)
- {
- k = -1 - k;
- e = pb->num_eqs++;
- gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
- omega_copy_eqn (&pb->eqs[e], &pb->subs[k], pb->num_vars);
- pb->eqs[e].coef[0] -= value;
- }
- else
- {
- e = pb->num_eqs++;
- omega_init_eqn_zero (&pb->eqs[e], pb->num_vars);
- pb->eqs[e].coef[k] = 1;
- pb->eqs[e].coef[0] = -value;
- }
- pb->eqs[e].color = color;
- }
- /* Return false when the upper and lower bounds are not coupled.
- Initialize the bounds LOWER_BOUND and UPPER_BOUND for the values of
- variable I. */
- bool
- omega_query_variable (omega_pb pb, int i, int *lower_bound, int *upper_bound)
- {
- int n_vars = pb->num_vars;
- int e, j;
- bool is_simple;
- bool coupled = false;
- *lower_bound = neg_infinity;
- *upper_bound = pos_infinity;
- i = pb->forwarding_address[i];
- if (i < 0)
- {
- i = -i - 1;
- for (j = 1; j <= n_vars; j++)
- if (pb->subs[i].coef[j] != 0)
- return true;
- *upper_bound = *lower_bound = pb->subs[i].coef[0];
- return false;
- }
- for (e = pb->num_subs - 1; e >= 0; e--)
- if (pb->subs[e].coef[i] != 0)
- {
- coupled = true;
- break;
- }
- for (e = pb->num_eqs - 1; e >= 0; e--)
- if (pb->eqs[e].coef[i] != 0)
- {
- is_simple = true;
- for (j = 1; j <= n_vars; j++)
- if (i != j && pb->eqs[e].coef[j] != 0)
- {
- is_simple = false;
- coupled = true;
- break;
- }
- if (!is_simple)
- continue;
- else
- {
- *lower_bound = *upper_bound =
- -pb->eqs[e].coef[i] * pb->eqs[e].coef[0];
- return false;
- }
- }
- for (e = pb->num_geqs - 1; e >= 0; e--)
- if (pb->geqs[e].coef[i] != 0)
- {
- if (pb->geqs[e].key == i)
- *lower_bound = MAX (*lower_bound, -pb->geqs[e].coef[0]);
- else if (pb->geqs[e].key == -i)
- *upper_bound = MIN (*upper_bound, pb->geqs[e].coef[0]);
- else
- coupled = true;
- }
- return coupled;
- }
- /* Sets the lower bound L and upper bound U for the values of variable
- I, and sets COULD_BE_ZERO to true if variable I might take value
- zero. LOWER_BOUND and UPPER_BOUND are bounds on the values of
- variable I. */
- static void
- query_coupled_variable (omega_pb pb, int i, int *l, int *u,
- bool *could_be_zero, int lower_bound, int upper_bound)
- {
- int e, b1, b2;
- eqn eqn;
- int sign;
- int v;
- /* Preconditions. */
- gcc_assert (abs (pb->forwarding_address[i]) == 1
- && pb->num_vars + pb->num_subs == 2
- && pb->num_eqs + pb->num_subs == 1);
- /* Define variable I in terms of variable V. */
- if (pb->forwarding_address[i] == -1)
- {
- eqn = &pb->subs[0];
- sign = 1;
- v = 1;
- }
- else
- {
- eqn = &pb->eqs[0];
- sign = -eqn->coef[1];
- v = 2;
- }
- for (e = pb->num_geqs - 1; e >= 0; e--)
- if (pb->geqs[e].coef[v] != 0)
- {
- if (pb->geqs[e].coef[v] == 1)
- lower_bound = MAX (lower_bound, -pb->geqs[e].coef[0]);
- else
- upper_bound = MIN (upper_bound, pb->geqs[e].coef[0]);
- }
- if (lower_bound > upper_bound)
- {
- *l = pos_infinity;
- *u = neg_infinity;
- *could_be_zero = 0;
- return;
- }
- if (lower_bound == neg_infinity)
- {
- if (eqn->coef[v] > 0)
- b1 = sign * neg_infinity;
- else
- b1 = -sign * neg_infinity;
- }
- else
- b1 = sign * (eqn->coef[0] + eqn->coef[v] * lower_bound);
- if (upper_bound == pos_infinity)
- {
- if (eqn->coef[v] > 0)
- b2 = sign * pos_infinity;
- else
- b2 = -sign * pos_infinity;
- }
- else
- b2 = sign * (eqn->coef[0] + eqn->coef[v] * upper_bound);
- *l = MAX (*l, b1 <= b2 ? b1 : b2);
- *u = MIN (*u, b1 <= b2 ? b2 : b1);
- *could_be_zero = (*l <= 0 && 0 <= *u
- && int_mod (eqn->coef[0], abs (eqn->coef[v])) == 0);
- }
- /* Return false when a lower bound L and an upper bound U for variable
- I in problem PB have been initialized. */
- bool
- omega_query_variable_bounds (omega_pb pb, int i, int *l, int *u)
- {
- *l = neg_infinity;
- *u = pos_infinity;
- if (!omega_query_variable (pb, i, l, u)
- || (pb->num_vars == 1 && pb->forwarding_address[i] == 1))
- return false;
- if (abs (pb->forwarding_address[i]) == 1
- && pb->num_vars + pb->num_subs == 2
- && pb->num_eqs + pb->num_subs == 1)
- {
- bool could_be_zero;
- query_coupled_variable (pb, i, l, u, &could_be_zero, neg_infinity,
- pos_infinity);
- return false;
- }
- return true;
- }
- /* For problem PB, return an integer that represents the classic data
- dependence direction in function of the DD_LT, DD_EQ and DD_GT bit
- masks that are added to the result. When DIST_KNOWN is true, DIST
- is set to the classic data dependence distance. LOWER_BOUND and
- UPPER_BOUND are bounds on the value of variable I, for example, it
- is possible to narrow the iteration domain with safe approximations
- of loop counts, and thus discard some data dependences that cannot
- occur. */
- int
- omega_query_variable_signs (omega_pb pb, int i, int dd_lt,
- int dd_eq, int dd_gt, int lower_bound,
- int upper_bound, bool *dist_known, int *dist)
- {
- int result;
- int l, u;
- bool could_be_zero;
- l = neg_infinity;
- u = pos_infinity;
- omega_query_variable (pb, i, &l, &u);
- query_coupled_variable (pb, i, &l, &u, &could_be_zero, lower_bound,
- upper_bound);
- result = 0;
- if (l < 0)
- result |= dd_gt;
- if (u > 0)
- result |= dd_lt;
- if (could_be_zero)
- result |= dd_eq;
- if (l == u)
- {
- *dist_known = true;
- *dist = l;
- }
- else
- *dist_known = false;
- return result;
- }
- /* Initialize PB as an Omega problem with NVARS variables and NPROT
- safe variables. Safe variables are not eliminated during the
- Fourier-Motzkin elimination. Safe variables are all those
- variables that are placed at the beginning of the array of
- variables: P->var[0, ..., NPROT - 1]. */
- omega_pb
- omega_alloc_problem (int nvars, int nprot)
- {
- omega_pb pb;
- gcc_assert (nvars <= OMEGA_MAX_VARS);
- omega_initialize ();
- /* Allocate and initialize PB. */
- pb = XCNEW (struct omega_pb_d);
- pb->var = XCNEWVEC (int, OMEGA_MAX_VARS + 2);
- pb->forwarding_address = XCNEWVEC (int, OMEGA_MAX_VARS + 2);
- pb->geqs = omega_alloc_eqns (0, OMEGA_MAX_GEQS);
- pb->eqs = omega_alloc_eqns (0, OMEGA_MAX_EQS);
- pb->subs = omega_alloc_eqns (0, OMEGA_MAX_VARS + 1);
- pb->hash_version = hash_version;
- pb->num_vars = nvars;
- pb->safe_vars = nprot;
- pb->variables_initialized = false;
- pb->variables_freed = false;
- pb->num_eqs = 0;
- pb->num_geqs = 0;
- pb->num_subs = 0;
- return pb;
- }
- /* Keeps the state of the initialization. */
- static bool omega_initialized = false;
- /* Initialization of the Omega solver. */
- void
- omega_initialize (void)
- {
- int i;
- if (omega_initialized)
- return;
- next_wild_card = 0;
- next_key = OMEGA_MAX_VARS + 1;
- packing = XCNEWVEC (int, OMEGA_MAX_VARS);
- fast_lookup = XCNEWVEC (int, MAX_KEYS * 2);
- fast_lookup_red = XCNEWVEC (int, MAX_KEYS * 2);
- hash_master = omega_alloc_eqns (0, HASH_TABLE_SIZE);
- for (i = 0; i < HASH_TABLE_SIZE; i++)
- hash_master[i].touched = -1;
- sprintf (wild_name[0], "1");
- sprintf (wild_name[1], "a");
- sprintf (wild_name[2], "b");
- sprintf (wild_name[3], "c");
- sprintf (wild_name[4], "d");
- sprintf (wild_name[5], "e");
- sprintf (wild_name[6], "f");
- sprintf (wild_name[7], "g");
- sprintf (wild_name[8], "h");
- sprintf (wild_name[9], "i");
- sprintf (wild_name[10], "j");
- sprintf (wild_name[11], "k");
- sprintf (wild_name[12], "l");
- sprintf (wild_name[13], "m");
- sprintf (wild_name[14], "n");
- sprintf (wild_name[15], "o");
- sprintf (wild_name[16], "p");
- sprintf (wild_name[17], "q");
- sprintf (wild_name[18], "r");
- sprintf (wild_name[19], "s");
- sprintf (wild_name[20], "t");
- sprintf (wild_name[40 - 1], "alpha");
- sprintf (wild_name[40 - 2], "beta");
- sprintf (wild_name[40 - 3], "gamma");
- sprintf (wild_name[40 - 4], "delta");
- sprintf (wild_name[40 - 5], "tau");
- sprintf (wild_name[40 - 6], "sigma");
- sprintf (wild_name[40 - 7], "chi");
- sprintf (wild_name[40 - 8], "omega");
- sprintf (wild_name[40 - 9], "pi");
- sprintf (wild_name[40 - 10], "ni");
- sprintf (wild_name[40 - 11], "Alpha");
- sprintf (wild_name[40 - 12], "Beta");
- sprintf (wild_name[40 - 13], "Gamma");
- sprintf (wild_name[40 - 14], "Delta");
- sprintf (wild_name[40 - 15], "Tau");
- sprintf (wild_name[40 - 16], "Sigma");
- sprintf (wild_name[40 - 17], "Chi");
- sprintf (wild_name[40 - 18], "Omega");
- sprintf (wild_name[40 - 19], "xxx");
- omega_initialized = true;
- }
|