genautomata.c 297 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835783678377838783978407841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910791179127913791479157916791779187919792079217922792379247925792679277928792979307931793279337934793579367937793879397940794179427943794479457946794779487949795079517952795379547955795679577958795979607961796279637964796579667967796879697970797179727973797479757976797779787979798079817982798379847985798679877988798979907991799279937994799579967997799879998000800180028003800480058006800780088009801080118012801380148015801680178018801980208021802280238024802580268027802880298030803180328033803480358036803780388039804080418042804380448045804680478048804980508051805280538054805580568057805880598060806180628063806480658066806780688069807080718072807380748075807680778078807980808081808280838084808580868087808880898090809180928093809480958096809780988099810081018102810381048105810681078108810981108111811281138114811581168117811881198120812181228123812481258126812781288129813081318132813381348135813681378138813981408141814281438144814581468147814881498150815181528153815481558156815781588159816081618162816381648165816681678168816981708171817281738174817581768177817881798180818181828183818481858186818781888189819081918192819381948195819681978198819982008201820282038204820582068207820882098210821182128213821482158216821782188219822082218222822382248225822682278228822982308231823282338234823582368237823882398240824182428243824482458246824782488249825082518252825382548255825682578258825982608261826282638264826582668267826882698270827182728273827482758276827782788279828082818282828382848285828682878288828982908291829282938294829582968297829882998300830183028303830483058306830783088309831083118312831383148315831683178318831983208321832283238324832583268327832883298330833183328333833483358336833783388339834083418342834383448345834683478348834983508351835283538354835583568357835883598360836183628363836483658366836783688369837083718372837383748375837683778378837983808381838283838384838583868387838883898390839183928393839483958396839783988399840084018402840384048405840684078408840984108411841284138414841584168417841884198420842184228423842484258426842784288429843084318432843384348435843684378438843984408441844284438444844584468447844884498450845184528453845484558456845784588459846084618462846384648465846684678468846984708471847284738474847584768477847884798480848184828483848484858486848784888489849084918492849384948495849684978498849985008501850285038504850585068507850885098510851185128513851485158516851785188519852085218522852385248525852685278528852985308531853285338534853585368537853885398540854185428543854485458546854785488549855085518552855385548555855685578558855985608561856285638564856585668567856885698570857185728573857485758576857785788579858085818582858385848585858685878588858985908591859285938594859585968597859885998600860186028603860486058606860786088609861086118612861386148615861686178618861986208621862286238624862586268627862886298630863186328633863486358636863786388639864086418642864386448645864686478648864986508651865286538654865586568657865886598660866186628663866486658666866786688669867086718672867386748675867686778678867986808681868286838684868586868687868886898690869186928693869486958696869786988699870087018702870387048705870687078708870987108711871287138714871587168717871887198720872187228723872487258726872787288729873087318732873387348735873687378738873987408741874287438744874587468747874887498750875187528753875487558756875787588759876087618762876387648765876687678768876987708771877287738774877587768777877887798780878187828783878487858786878787888789879087918792879387948795879687978798879988008801880288038804880588068807880888098810881188128813881488158816881788188819882088218822882388248825882688278828882988308831883288338834883588368837883888398840884188428843884488458846884788488849885088518852885388548855885688578858885988608861886288638864886588668867886888698870887188728873887488758876887788788879888088818882888388848885888688878888888988908891889288938894889588968897889888998900890189028903890489058906890789088909891089118912891389148915891689178918891989208921892289238924892589268927892889298930893189328933893489358936893789388939894089418942894389448945894689478948894989508951895289538954895589568957895889598960896189628963896489658966896789688969897089718972897389748975897689778978897989808981898289838984898589868987898889898990899189928993899489958996899789988999900090019002900390049005900690079008900990109011901290139014901590169017901890199020902190229023902490259026902790289029903090319032903390349035903690379038903990409041904290439044904590469047904890499050905190529053905490559056905790589059906090619062906390649065906690679068906990709071907290739074907590769077907890799080908190829083908490859086908790889089909090919092909390949095909690979098909991009101910291039104910591069107910891099110911191129113911491159116911791189119912091219122912391249125912691279128912991309131913291339134913591369137913891399140914191429143914491459146914791489149915091519152915391549155915691579158915991609161916291639164916591669167916891699170917191729173917491759176917791789179918091819182918391849185918691879188918991909191919291939194919591969197919891999200920192029203920492059206920792089209921092119212921392149215921692179218921992209221922292239224922592269227922892299230923192329233923492359236923792389239924092419242924392449245924692479248924992509251925292539254925592569257925892599260926192629263926492659266926792689269927092719272927392749275927692779278927992809281928292839284928592869287928892899290929192929293929492959296929792989299930093019302930393049305930693079308930993109311931293139314931593169317931893199320932193229323932493259326932793289329933093319332933393349335933693379338933993409341934293439344934593469347934893499350935193529353935493559356935793589359936093619362936393649365936693679368936993709371937293739374937593769377937893799380938193829383938493859386938793889389939093919392939393949395939693979398939994009401940294039404940594069407940894099410941194129413941494159416941794189419942094219422942394249425942694279428942994309431943294339434943594369437943894399440944194429443944494459446944794489449945094519452945394549455945694579458945994609461946294639464946594669467946894699470947194729473947494759476947794789479948094819482948394849485948694879488948994909491949294939494949594969497949894999500950195029503950495059506950795089509951095119512951395149515951695179518951995209521952295239524952595269527952895299530953195329533953495359536953795389539954095419542954395449545954695479548954995509551955295539554955595569557955895599560956195629563956495659566956795689569957095719572957395749575957695779578957995809581958295839584958595869587958895899590959195929593959495959596959795989599960096019602960396049605960696079608960996109611961296139614961596169617961896199620962196229623962496259626962796289629963096319632963396349635963696379638963996409641964296439644964596469647964896499650965196529653965496559656965796589659966096619662966396649665966696679668966996709671967296739674967596769677967896799680968196829683968496859686968796889689969096919692969396949695969696979698969997009701970297039704970597069707970897099710971197129713971497159716971797189719972097219722
  1. /* Pipeline hazard description translator.
  2. Copyright (C) 2000-2015 Free Software Foundation, Inc.
  3. Written by Vladimir Makarov <vmakarov@redhat.com>
  4. This file is part of GCC.
  5. GCC is free software; you can redistribute it and/or modify it
  6. under the terms of the GNU General Public License as published by the
  7. Free Software Foundation; either version 3, or (at your option) any
  8. later version.
  9. GCC is distributed in the hope that it will be useful, but WITHOUT
  10. ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11. FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  12. for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with GCC; see the file COPYING3. If not see
  15. <http://www.gnu.org/licenses/>. */
  16. /* References:
  17. 1. The finite state automaton based pipeline hazard recognizer and
  18. instruction scheduler in GCC. V. Makarov. Proceedings of GCC
  19. summit, 2003.
  20. 2. Detecting pipeline structural hazards quickly. T. Proebsting,
  21. C. Fraser. Proceedings of ACM SIGPLAN-SIGACT Symposium on
  22. Principles of Programming Languages, pages 280--286, 1994.
  23. This article is a good start point to understand usage of finite
  24. state automata for pipeline hazard recognizers. But I'd
  25. recommend the 1st and 3rd article for more deep understanding.
  26. 3. Efficient Instruction Scheduling Using Finite State Automata:
  27. V. Bala and N. Rubin, Proceedings of MICRO-28. This is the best
  28. article about usage of finite state automata for pipeline hazard
  29. recognizers.
  30. The current implementation is described in the 1st article and it
  31. is different from the 3rd article in the following:
  32. 1. New operator `|' (alternative) is permitted in functional unit
  33. reservation which can be treated deterministically and
  34. non-deterministically.
  35. 2. Possibility of usage of nondeterministic automata too.
  36. 3. Possibility to query functional unit reservations for given
  37. automaton state.
  38. 4. Several constructions to describe impossible reservations
  39. (`exclusion_set', `presence_set', `final_presence_set',
  40. `absence_set', and `final_absence_set').
  41. 5. No reverse automata are generated. Trace instruction scheduling
  42. requires this. It can be easily added in the future if we
  43. really need this.
  44. 6. Union of automaton states are not generated yet. It is planned
  45. to be implemented. Such feature is needed to make more accurate
  46. interlock insn scheduling to get state describing functional
  47. unit reservation in a joint CFG point. */
  48. /* This file code processes constructions of machine description file
  49. which describes automaton used for recognition of processor pipeline
  50. hazards by insn scheduler and can be used for other tasks (such as
  51. VLIW insn packing.
  52. The translator functions `gen_cpu_unit', `gen_query_cpu_unit',
  53. `gen_bypass', `gen_excl_set', `gen_presence_set',
  54. `gen_final_presence_set', `gen_absence_set',
  55. `gen_final_absence_set', `gen_automaton', `gen_automata_option',
  56. `gen_reserv', `gen_insn_reserv' are called from file
  57. `genattrtab.c'. They transform RTL constructions describing
  58. automata in .md file into internal representation convenient for
  59. further processing.
  60. The translator major function `expand_automata' processes the
  61. description internal representation into finite state automaton.
  62. It can be divided on:
  63. o checking correctness of the automaton pipeline description
  64. (major function is `check_all_description').
  65. o generating automaton (automata) from the description (major
  66. function is `make_automaton').
  67. o optional transformation of nondeterministic finite state
  68. automata into deterministic ones if the alternative operator
  69. `|' is treated nondeterministically in the description (major
  70. function is NDFA_to_DFA).
  71. o optional minimization of the finite state automata by merging
  72. equivalent automaton states (major function is `minimize_DFA').
  73. o forming tables (some as comb vectors) and attributes
  74. representing the automata (functions output_..._table).
  75. Function `write_automata' outputs the created finite state
  76. automaton as different tables and functions which works with the
  77. automata to inquire automaton state and to change its state. These
  78. function are used by gcc instruction scheduler and may be some
  79. other gcc code. */
  80. #include "bconfig.h"
  81. #include "system.h"
  82. #include "coretypes.h"
  83. #include "tm.h"
  84. #include "rtl.h"
  85. #include "obstack.h"
  86. #include "errors.h"
  87. #include "gensupport.h"
  88. #include <math.h>
  89. #include "hashtab.h"
  90. #include "vec.h"
  91. #include "fnmatch.h"
  92. #ifndef CHAR_BIT
  93. #define CHAR_BIT 8
  94. #endif
  95. /* Positions in machine description file. Now they are not used. But
  96. they could be used in the future for better diagnostic messages. */
  97. typedef int pos_t;
  98. /* The following is element of vector of current (and planned in the
  99. future) functional unit reservations. */
  100. typedef unsigned HOST_WIDE_INT set_el_t;
  101. /* Reservations of function units are represented by value of the following
  102. type. */
  103. typedef set_el_t *reserv_sets_t;
  104. typedef const set_el_t *const_reserv_sets_t;
  105. /* The following structure describes a ticker. */
  106. struct ticker
  107. {
  108. /* The following member value is time of the ticker creation with
  109. taking into account time when the ticker is off. Active time of
  110. the ticker is current time minus the value. */
  111. int modified_creation_time;
  112. /* The following member value is time (incremented by one) when the
  113. ticker was off. Zero value means that now the ticker is on. */
  114. int incremented_off_time;
  115. };
  116. /* The ticker is represented by the following type. */
  117. typedef struct ticker ticker_t;
  118. /* The following type describes elements of output vectors. */
  119. typedef HOST_WIDE_INT vect_el_t;
  120. /* Forward declaration of structures of internal representation of
  121. pipeline description based on NDFA. */
  122. struct unit_decl;
  123. struct bypass_decl;
  124. struct result_decl;
  125. struct automaton_decl;
  126. struct unit_pattern_rel_decl;
  127. struct reserv_decl;
  128. struct insn_reserv_decl;
  129. struct decl;
  130. struct unit_regexp;
  131. struct result_regexp;
  132. struct reserv_regexp;
  133. struct nothing_regexp;
  134. struct sequence_regexp;
  135. struct repeat_regexp;
  136. struct allof_regexp;
  137. struct oneof_regexp;
  138. struct regexp;
  139. struct description;
  140. struct unit_set_el;
  141. struct pattern_set_el;
  142. struct pattern_reserv;
  143. struct state;
  144. struct alt_state;
  145. struct arc;
  146. struct ainsn;
  147. struct automaton;
  148. struct state_ainsn_table;
  149. /* The following typedefs are for brevity. */
  150. typedef struct unit_decl *unit_decl_t;
  151. typedef const struct unit_decl *const_unit_decl_t;
  152. typedef struct decl *decl_t;
  153. typedef const struct decl *const_decl_t;
  154. typedef struct regexp *regexp_t;
  155. typedef struct unit_set_el *unit_set_el_t;
  156. typedef struct pattern_set_el *pattern_set_el_t;
  157. typedef struct pattern_reserv *pattern_reserv_t;
  158. typedef struct alt_state *alt_state_t;
  159. typedef struct state *state_t;
  160. typedef const struct state *const_state_t;
  161. typedef struct arc *arc_t;
  162. typedef struct ainsn *ainsn_t;
  163. typedef struct automaton *automaton_t;
  164. typedef struct automata_list_el *automata_list_el_t;
  165. typedef const struct automata_list_el *const_automata_list_el_t;
  166. typedef struct state_ainsn_table *state_ainsn_table_t;
  167. /* Undefined position. */
  168. static pos_t no_pos = 0;
  169. /* All IR is stored in the following obstack. */
  170. static struct obstack irp;
  171. /* Declare vector types for various data structures: */
  172. typedef vec<vect_el_t> vla_hwint_t;
  173. /* Forward declarations of functions used before their definitions, only. */
  174. static regexp_t gen_regexp_sequence (const char *);
  175. static void reserv_sets_or (reserv_sets_t, reserv_sets_t,
  176. reserv_sets_t);
  177. static reserv_sets_t get_excl_set (reserv_sets_t);
  178. static int check_presence_pattern_sets (reserv_sets_t,
  179. reserv_sets_t, int);
  180. static int check_absence_pattern_sets (reserv_sets_t, reserv_sets_t,
  181. int);
  182. static arc_t first_out_arc (const_state_t);
  183. static arc_t next_out_arc (arc_t);
  184. /* Options with the following names can be set up in automata_option
  185. construction. Because the strings occur more one time we use the
  186. macros. */
  187. #define NO_MINIMIZATION_OPTION "-no-minimization"
  188. #define TIME_OPTION "-time"
  189. #define STATS_OPTION "-stats"
  190. #define V_OPTION "-v"
  191. #define W_OPTION "-w"
  192. #define NDFA_OPTION "-ndfa"
  193. #define COLLAPSE_OPTION "-collapse-ndfa"
  194. #define NO_COMB_OPTION "-no-comb-vect"
  195. #define PROGRESS_OPTION "-progress"
  196. /* The following flags are set up by function `initiate_automaton_gen'. */
  197. /* Make automata with nondeterministic reservation by insns (`-ndfa'). */
  198. static int ndfa_flag;
  199. /* When making an NDFA, produce additional transitions that collapse
  200. NDFA state into a deterministic one suitable for querying CPU units.
  201. Provide avance-state transitions only for deterministic states. */
  202. static int collapse_flag;
  203. /* Do not make minimization of DFA (`-no-minimization'). */
  204. static int no_minimization_flag;
  205. /* Do not try to generate a comb vector (`-no-comb-vect'). */
  206. static int no_comb_flag;
  207. /* Value of this variable is number of automata being generated. The
  208. actual number of automata may be less this value if there is not
  209. sufficient number of units. This value is defined by argument of
  210. option `-split' or by constructions automaton if the value is zero
  211. (it is default value of the argument). */
  212. static int split_argument;
  213. /* Flag of output time statistics (`-time'). */
  214. static int time_flag;
  215. /* Flag of automata statistics (`-stats'). */
  216. static int stats_flag;
  217. /* Flag of creation of description file which contains description of
  218. result automaton and statistics information (`-v'). */
  219. static int v_flag;
  220. /* Flag of output of a progress bar showing how many states were
  221. generated so far for automaton being processed (`-progress'). */
  222. static int progress_flag;
  223. /* Flag of generating warning instead of error for non-critical errors
  224. (`-w'). */
  225. static int w_flag;
  226. /* Output file for pipeline hazard recognizer (PHR) being generated.
  227. The value is NULL if the file is not defined. */
  228. static FILE *output_file;
  229. /* Description file of PHR. The value is NULL if the file is not
  230. created. */
  231. static FILE *output_description_file;
  232. /* PHR description file name. */
  233. static char *output_description_file_name;
  234. /* Value of the following variable is node representing description
  235. being processed. This is start point of IR. */
  236. static struct description *description;
  237. /* This page contains description of IR structure (nodes). */
  238. enum decl_mode
  239. {
  240. dm_unit,
  241. dm_bypass,
  242. dm_automaton,
  243. dm_excl,
  244. dm_presence,
  245. dm_absence,
  246. dm_reserv,
  247. dm_insn_reserv
  248. };
  249. /* This describes define_cpu_unit and define_query_cpu_unit (see file
  250. rtl.def). */
  251. struct unit_decl
  252. {
  253. const char *name;
  254. /* NULL if the automaton name is absent. */
  255. const char *automaton_name;
  256. /* If the following value is not zero, the cpu unit reservation is
  257. described in define_query_cpu_unit. */
  258. char query_p;
  259. /* The following fields are defined by checker. */
  260. /* The following field value is nonzero if the unit is used in an
  261. regexp. */
  262. char unit_is_used;
  263. /* The following field value is order number (0, 1, ...) of given
  264. unit. */
  265. int unit_num;
  266. /* The following field value is corresponding declaration of
  267. automaton which was given in description. If the field value is
  268. NULL then automaton in the unit declaration was absent. */
  269. struct automaton_decl *automaton_decl;
  270. /* The following field value is maximal cycle number (1, ...) on
  271. which given unit occurs in insns. Zero value means that given
  272. unit is not used in insns. */
  273. int max_occ_cycle_num;
  274. /* The following field value is minimal cycle number (0, ...) on
  275. which given unit occurs in insns. -1 value means that given
  276. unit is not used in insns. */
  277. int min_occ_cycle_num;
  278. /* The following list contains units which conflict with given
  279. unit. */
  280. unit_set_el_t excl_list;
  281. /* The following list contains patterns which are required to
  282. reservation of given unit. */
  283. pattern_set_el_t presence_list;
  284. pattern_set_el_t final_presence_list;
  285. /* The following list contains patterns which should be not present
  286. in reservation for given unit. */
  287. pattern_set_el_t absence_list;
  288. pattern_set_el_t final_absence_list;
  289. /* The following is used only when `query_p' has nonzero value.
  290. This is query number for the unit. */
  291. int query_num;
  292. /* The following is the last cycle on which the unit was checked for
  293. correct distributions of units to automata in a regexp. */
  294. int last_distribution_check_cycle;
  295. /* The following fields are defined by automaton generator. */
  296. /* The following field value is number of the automaton to which
  297. given unit belongs. */
  298. int corresponding_automaton_num;
  299. /* If the following value is not zero, the cpu unit is present in a
  300. `exclusion_set' or in right part of a `presence_set',
  301. `final_presence_set', `absence_set', and
  302. `final_absence_set'define_query_cpu_unit. */
  303. char in_set_p;
  304. };
  305. /* This describes define_bypass (see file rtl.def). */
  306. struct bypass_decl
  307. {
  308. int latency;
  309. const char *out_pattern;
  310. const char *in_pattern;
  311. const char *bypass_guard_name;
  312. /* The following fields are defined by checker. */
  313. /* output and input insns of given bypass. */
  314. struct insn_reserv_decl *out_insn_reserv;
  315. struct insn_reserv_decl *in_insn_reserv;
  316. /* The next bypass for given output insn. */
  317. struct bypass_decl *next;
  318. };
  319. /* This describes define_automaton (see file rtl.def). */
  320. struct automaton_decl
  321. {
  322. const char *name;
  323. /* The following fields are defined by automaton generator. */
  324. /* The following field value is nonzero if the automaton is used in
  325. an regexp definition. */
  326. char automaton_is_used;
  327. /* The following fields are defined by checker. */
  328. /* The following field value is the corresponding automaton. This
  329. field is not NULL only if the automaton is present in unit
  330. declarations and the automatic partition on automata is not
  331. used. */
  332. automaton_t corresponding_automaton;
  333. };
  334. /* This describes exclusion relations: exclusion_set (see file
  335. rtl.def). */
  336. struct excl_rel_decl
  337. {
  338. int all_names_num;
  339. int first_list_length;
  340. char *names [1];
  341. };
  342. /* This describes unit relations: [final_]presence_set or
  343. [final_]absence_set (see file rtl.def). */
  344. struct unit_pattern_rel_decl
  345. {
  346. int final_p;
  347. int names_num;
  348. int patterns_num;
  349. char **names;
  350. char ***patterns;
  351. };
  352. /* This describes define_reservation (see file rtl.def). */
  353. struct reserv_decl
  354. {
  355. const char *name;
  356. regexp_t regexp;
  357. /* The following fields are defined by checker. */
  358. /* The following field value is nonzero if the unit is used in an
  359. regexp. */
  360. char reserv_is_used;
  361. /* The following field is used to check up cycle in expression
  362. definition. */
  363. int loop_pass_num;
  364. };
  365. /* This describes define_insn_reservation (see file rtl.def). */
  366. struct insn_reserv_decl
  367. {
  368. rtx condexp;
  369. int default_latency;
  370. regexp_t regexp;
  371. const char *name;
  372. /* The following fields are defined by checker. */
  373. /* The following field value is order number (0, 1, ...) of given
  374. insn. */
  375. int insn_num;
  376. /* The following field value is list of bypasses in which given insn
  377. is output insn. Bypasses with the same input insn stay one after
  378. another in the list in the same order as their occurrences in the
  379. description but the bypass without a guard stays always the last
  380. in a row of bypasses with the same input insn. */
  381. struct bypass_decl *bypass_list;
  382. /* The following fields are defined by automaton generator. */
  383. /* The following field is the insn regexp transformed that
  384. the regexp has not optional regexp, repetition regexp, and an
  385. reservation name (i.e. reservation identifiers are changed by the
  386. corresponding regexp) and all alternations are the top level
  387. of the regexp. The value can be NULL only if it is special
  388. insn `cycle advancing'. */
  389. regexp_t transformed_regexp;
  390. /* The following field value is list of arcs marked given
  391. insn. The field is used in transformation NDFA -> DFA. */
  392. arc_t arcs_marked_by_insn;
  393. /* The two following fields are used during minimization of a finite state
  394. automaton. */
  395. /* The field value is number of equivalence class of state into
  396. which arc marked by given insn enters from a state (fixed during
  397. an automaton minimization). */
  398. int equiv_class_num;
  399. /* The following member value is the list to automata which can be
  400. changed by the insn issue. */
  401. automata_list_el_t important_automata_list;
  402. /* The following member is used to process insn once for output. */
  403. int processed_p;
  404. };
  405. /* This contains a declaration mentioned above. */
  406. struct decl
  407. {
  408. /* What node in the union? */
  409. enum decl_mode mode;
  410. pos_t pos;
  411. union
  412. {
  413. struct unit_decl unit;
  414. struct bypass_decl bypass;
  415. struct automaton_decl automaton;
  416. struct excl_rel_decl excl;
  417. struct unit_pattern_rel_decl presence;
  418. struct unit_pattern_rel_decl absence;
  419. struct reserv_decl reserv;
  420. struct insn_reserv_decl insn_reserv;
  421. } decl;
  422. };
  423. /* The following structures represent parsed reservation strings. */
  424. enum regexp_mode
  425. {
  426. rm_unit,
  427. rm_reserv,
  428. rm_nothing,
  429. rm_sequence,
  430. rm_repeat,
  431. rm_allof,
  432. rm_oneof
  433. };
  434. /* Cpu unit in reservation. */
  435. struct unit_regexp
  436. {
  437. const char *name;
  438. unit_decl_t unit_decl;
  439. };
  440. /* Define_reservation in a reservation. */
  441. struct reserv_regexp
  442. {
  443. const char *name;
  444. struct reserv_decl *reserv_decl;
  445. };
  446. /* Absence of reservation (represented by string `nothing'). */
  447. struct nothing_regexp
  448. {
  449. /* This used to be empty but ISO C doesn't allow that. */
  450. char unused;
  451. };
  452. /* Representation of reservations separated by ',' (see file
  453. rtl.def). */
  454. struct sequence_regexp
  455. {
  456. int regexps_num;
  457. regexp_t regexps [1];
  458. };
  459. /* Representation of construction `repeat' (see file rtl.def). */
  460. struct repeat_regexp
  461. {
  462. int repeat_num;
  463. regexp_t regexp;
  464. };
  465. /* Representation of reservations separated by '+' (see file
  466. rtl.def). */
  467. struct allof_regexp
  468. {
  469. int regexps_num;
  470. regexp_t regexps [1];
  471. };
  472. /* Representation of reservations separated by '|' (see file
  473. rtl.def). */
  474. struct oneof_regexp
  475. {
  476. int regexps_num;
  477. regexp_t regexps [1];
  478. };
  479. /* Representation of a reservation string. */
  480. struct regexp
  481. {
  482. /* What node in the union? */
  483. enum regexp_mode mode;
  484. pos_t pos;
  485. union
  486. {
  487. struct unit_regexp unit;
  488. struct reserv_regexp reserv;
  489. struct nothing_regexp nothing;
  490. struct sequence_regexp sequence;
  491. struct repeat_regexp repeat;
  492. struct allof_regexp allof;
  493. struct oneof_regexp oneof;
  494. } regexp;
  495. };
  496. /* Represents description of pipeline hazard description based on
  497. NDFA. */
  498. struct description
  499. {
  500. int decls_num, normal_decls_num;
  501. /* The following fields are defined by checker. */
  502. /* The following fields values are correspondingly number of all
  503. units, query units, and insns in the description. */
  504. int units_num;
  505. int query_units_num;
  506. int insns_num;
  507. /* The following field value is max length (in cycles) of
  508. reservations of insns. The field value is defined only for
  509. correct programs. */
  510. int max_insn_reserv_cycles;
  511. /* The following fields are defined by automaton generator. */
  512. /* The following field value is the first automaton. */
  513. automaton_t first_automaton;
  514. /* The following field is created by pipeline hazard parser and
  515. contains all declarations. We allocate additional entries for
  516. two special insns which are added by the automaton generator. */
  517. decl_t decls [1];
  518. };
  519. /* The following nodes are created in automaton checker. */
  520. /* The following nodes represent exclusion set for cpu units. Each
  521. element is accessed through only one excl_list. */
  522. struct unit_set_el
  523. {
  524. unit_decl_t unit_decl;
  525. unit_set_el_t next_unit_set_el;
  526. };
  527. /* The following nodes represent presence or absence pattern for cpu
  528. units. Each element is accessed through only one presence_list or
  529. absence_list. */
  530. struct pattern_set_el
  531. {
  532. /* The number of units in unit_decls. */
  533. int units_num;
  534. /* The units forming the pattern. */
  535. struct unit_decl **unit_decls;
  536. pattern_set_el_t next_pattern_set_el;
  537. };
  538. /* The following nodes are created in automaton generator. */
  539. /* The following nodes represent presence or absence pattern for cpu
  540. units. Each element is accessed through only one element of
  541. unit_presence_set_table or unit_absence_set_table. */
  542. struct pattern_reserv
  543. {
  544. reserv_sets_t reserv;
  545. pattern_reserv_t next_pattern_reserv;
  546. };
  547. /* The following node type describes state automaton. The state may
  548. be deterministic or non-deterministic. Non-deterministic state has
  549. several component states which represent alternative cpu units
  550. reservations. The state also is used for describing a
  551. deterministic reservation of automaton insn. */
  552. struct state
  553. {
  554. /* The following member value is nonzero if there is a transition by
  555. cycle advancing. */
  556. int new_cycle_p;
  557. /* The following field is list of processor unit reservations on
  558. each cycle. */
  559. reserv_sets_t reservs;
  560. /* The following field is unique number of given state between other
  561. states. */
  562. int unique_num;
  563. /* The following field value is automaton to which given state
  564. belongs. */
  565. automaton_t automaton;
  566. /* The following field value is the first arc output from given
  567. state. */
  568. arc_t first_out_arc;
  569. unsigned int num_out_arcs;
  570. /* The following field is used to form NDFA. */
  571. char it_was_placed_in_stack_for_NDFA_forming;
  572. /* The following field is used to form DFA. */
  573. char it_was_placed_in_stack_for_DFA_forming;
  574. /* The following field is used to transform NDFA to DFA and DFA
  575. minimization. The field value is not NULL if the state is a
  576. compound state. In this case the value of field `unit_sets_list'
  577. is NULL. All states in the list are in the hash table. The list
  578. is formed through field `next_sorted_alt_state'. We should
  579. support only one level of nesting state. */
  580. alt_state_t component_states;
  581. /* The following field is used for passing graph of states. */
  582. int pass_num;
  583. /* The list of states belonging to one equivalence class is formed
  584. with the aid of the following field. */
  585. state_t next_equiv_class_state;
  586. /* The two following fields are used during minimization of a finite
  587. state automaton. */
  588. int equiv_class_num_1, equiv_class_num_2;
  589. /* The following field is used during minimization of a finite state
  590. automaton. The field value is state corresponding to equivalence
  591. class to which given state belongs. */
  592. state_t equiv_class_state;
  593. unsigned int *presence_signature;
  594. /* The following field value is the order number of given state.
  595. The states in final DFA is enumerated with the aid of the
  596. following field. */
  597. int order_state_num;
  598. /* This member is used for passing states for searching minimal
  599. delay time. */
  600. int state_pass_num;
  601. /* The following member is used to evaluate min issue delay of insn
  602. for a state. */
  603. int min_insn_issue_delay;
  604. };
  605. /* Automaton arc. */
  606. struct arc
  607. {
  608. /* The following field refers for the state into which given arc
  609. enters. */
  610. state_t to_state;
  611. /* The following field describes that the insn issue (with cycle
  612. advancing for special insn `cycle advancing' and without cycle
  613. advancing for others) makes transition from given state to
  614. another given state. */
  615. ainsn_t insn;
  616. /* The following field value is the next arc output from the same
  617. state. */
  618. arc_t next_out_arc;
  619. /* List of arcs marked given insn is formed with the following
  620. field. The field is used in transformation NDFA -> DFA. */
  621. arc_t next_arc_marked_by_insn;
  622. };
  623. /* The following node type describes a deterministic alternative in
  624. non-deterministic state which characterizes cpu unit reservations
  625. of automaton insn or which is part of NDFA. */
  626. struct alt_state
  627. {
  628. /* The following field is a deterministic state which characterizes
  629. unit reservations of the instruction. */
  630. state_t state;
  631. /* The following field refers to the next state which characterizes
  632. unit reservations of the instruction. */
  633. alt_state_t next_alt_state;
  634. /* The following field refers to the next state in sorted list. */
  635. alt_state_t next_sorted_alt_state;
  636. };
  637. /* The following node type describes insn of automaton. They are
  638. labels of FA arcs. */
  639. struct ainsn
  640. {
  641. /* The following field value is the corresponding insn declaration
  642. of description. */
  643. struct insn_reserv_decl *insn_reserv_decl;
  644. /* The following field value is the next insn declaration for an
  645. automaton. */
  646. ainsn_t next_ainsn;
  647. /* The following field is states which characterize automaton unit
  648. reservations of the instruction. The value can be NULL only if it
  649. is special insn `cycle advancing'. */
  650. alt_state_t alt_states;
  651. /* The following field is sorted list of states which characterize
  652. automaton unit reservations of the instruction. The value can be
  653. NULL only if it is special insn `cycle advancing'. */
  654. alt_state_t sorted_alt_states;
  655. /* The following field refers the next automaton insn with
  656. the same reservations. */
  657. ainsn_t next_same_reservs_insn;
  658. /* The following field is flag of the first automaton insn with the
  659. same reservations in the declaration list. Only arcs marked such
  660. insn is present in the automaton. This significantly decreases
  661. memory requirements especially when several automata are
  662. formed. */
  663. char first_insn_with_same_reservs;
  664. /* The following member has nonzero value if there is arc from state of
  665. the automaton marked by the ainsn. */
  666. char arc_exists_p;
  667. /* Cyclic list of insns of an equivalence class is formed with the
  668. aid of the following field. */
  669. ainsn_t next_equiv_class_insn;
  670. /* The following field value is nonzero if the insn declaration is
  671. the first insn declaration with given equivalence number. */
  672. char first_ainsn_with_given_equivalence_num;
  673. /* The following field is number of class of equivalence of insns.
  674. It is necessary because many insns may be equivalent with the
  675. point of view of pipeline hazards. */
  676. int insn_equiv_class_num;
  677. /* The following member value is TRUE if there is an arc in the
  678. automaton marked by the insn into another state. In other
  679. words, the insn can change the state of the automaton. */
  680. int important_p;
  681. };
  682. /* The following describes an automaton for PHR. */
  683. struct automaton
  684. {
  685. /* The following field value is the list of insn declarations for
  686. given automaton. */
  687. ainsn_t ainsn_list;
  688. /* Pointers to the ainsns corresponding to the special reservations. */
  689. ainsn_t advance_ainsn, collapse_ainsn;
  690. /* The following field value is the corresponding automaton
  691. declaration. This field is not NULL only if the automatic
  692. partition on automata is not used. */
  693. struct automaton_decl *corresponding_automaton_decl;
  694. /* The following field value is the next automaton. */
  695. automaton_t next_automaton;
  696. /* The following field is start state of FA. There are not unit
  697. reservations in the state. */
  698. state_t start_state;
  699. /* The following field value is number of equivalence classes of
  700. insns (see field `insn_equiv_class_num' in
  701. `insn_reserv_decl'). */
  702. int insn_equiv_classes_num;
  703. /* The following field value is number of states of final DFA. */
  704. int achieved_states_num;
  705. /* The following field value is the order number (0, 1, ...) of
  706. given automaton. */
  707. int automaton_order_num;
  708. /* The following fields contain statistics information about
  709. building automaton. */
  710. int NDFA_states_num, DFA_states_num;
  711. /* The following field value is defined only if minimization of DFA
  712. is used. */
  713. int minimal_DFA_states_num;
  714. int NDFA_arcs_num, DFA_arcs_num;
  715. /* The following field value is defined only if minimization of DFA
  716. is used. */
  717. int minimal_DFA_arcs_num;
  718. /* The following member refers for two table state x ainsn -> int.
  719. ??? Above sentence is incomprehensible. */
  720. state_ainsn_table_t trans_table;
  721. /* The following member value is maximal value of min issue delay
  722. for insns of the automaton. */
  723. int max_min_delay;
  724. /* Usually min issue delay is small and we can place several (2, 4,
  725. 8) elements in one vector element. So the compression factor can
  726. be 1 (no compression), 2, 4, 8. */
  727. int min_issue_delay_table_compression_factor;
  728. /* Total number of locked states in this automaton. */
  729. int locked_states;
  730. };
  731. /* The following is the element of the list of automata. */
  732. struct automata_list_el
  733. {
  734. /* The automaton itself. */
  735. automaton_t automaton;
  736. /* The next automata set element. */
  737. automata_list_el_t next_automata_list_el;
  738. };
  739. /* The following structure describes a table state X ainsn -> int(>= 0). */
  740. struct state_ainsn_table
  741. {
  742. /* Automaton to which given table belongs. */
  743. automaton_t automaton;
  744. /* The following tree vectors for comb vector implementation of the
  745. table. */
  746. vla_hwint_t comb_vect;
  747. vla_hwint_t check_vect;
  748. vla_hwint_t base_vect;
  749. /* This is simple implementation of the table. */
  750. vla_hwint_t full_vect;
  751. /* Minimal and maximal values of the previous vectors. */
  752. int min_comb_vect_el_value, max_comb_vect_el_value;
  753. int min_base_vect_el_value, max_base_vect_el_value;
  754. };
  755. /* Macros to access members of unions. Use only them for access to
  756. union members of declarations and regexps. */
  757. #if defined ENABLE_CHECKING && (GCC_VERSION >= 2007)
  758. #define DECL_UNIT(d) __extension__ \
  759. (({ __typeof (d) const _decl = (d); \
  760. if (_decl->mode != dm_unit) \
  761. decl_mode_check_failed (_decl->mode, "dm_unit", \
  762. __FILE__, __LINE__, __FUNCTION__); \
  763. &(_decl)->decl.unit; }))
  764. #define DECL_BYPASS(d) __extension__ \
  765. (({ __typeof (d) const _decl = (d); \
  766. if (_decl->mode != dm_bypass) \
  767. decl_mode_check_failed (_decl->mode, "dm_bypass", \
  768. __FILE__, __LINE__, __FUNCTION__); \
  769. &(_decl)->decl.bypass; }))
  770. #define DECL_AUTOMATON(d) __extension__ \
  771. (({ __typeof (d) const _decl = (d); \
  772. if (_decl->mode != dm_automaton) \
  773. decl_mode_check_failed (_decl->mode, "dm_automaton", \
  774. __FILE__, __LINE__, __FUNCTION__); \
  775. &(_decl)->decl.automaton; }))
  776. #define DECL_EXCL(d) __extension__ \
  777. (({ __typeof (d) const _decl = (d); \
  778. if (_decl->mode != dm_excl) \
  779. decl_mode_check_failed (_decl->mode, "dm_excl", \
  780. __FILE__, __LINE__, __FUNCTION__); \
  781. &(_decl)->decl.excl; }))
  782. #define DECL_PRESENCE(d) __extension__ \
  783. (({ __typeof (d) const _decl = (d); \
  784. if (_decl->mode != dm_presence) \
  785. decl_mode_check_failed (_decl->mode, "dm_presence", \
  786. __FILE__, __LINE__, __FUNCTION__); \
  787. &(_decl)->decl.presence; }))
  788. #define DECL_ABSENCE(d) __extension__ \
  789. (({ __typeof (d) const _decl = (d); \
  790. if (_decl->mode != dm_absence) \
  791. decl_mode_check_failed (_decl->mode, "dm_absence", \
  792. __FILE__, __LINE__, __FUNCTION__); \
  793. &(_decl)->decl.absence; }))
  794. #define DECL_RESERV(d) __extension__ \
  795. (({ __typeof (d) const _decl = (d); \
  796. if (_decl->mode != dm_reserv) \
  797. decl_mode_check_failed (_decl->mode, "dm_reserv", \
  798. __FILE__, __LINE__, __FUNCTION__); \
  799. &(_decl)->decl.reserv; }))
  800. #define DECL_INSN_RESERV(d) __extension__ \
  801. (({ __typeof (d) const _decl = (d); \
  802. if (_decl->mode != dm_insn_reserv) \
  803. decl_mode_check_failed (_decl->mode, "dm_insn_reserv", \
  804. __FILE__, __LINE__, __FUNCTION__); \
  805. &(_decl)->decl.insn_reserv; }))
  806. static const char *decl_name (enum decl_mode);
  807. static void decl_mode_check_failed (enum decl_mode, const char *,
  808. const char *, int, const char *)
  809. ATTRIBUTE_NORETURN;
  810. /* Return string representation of declaration mode MODE. */
  811. static const char *
  812. decl_name (enum decl_mode mode)
  813. {
  814. static char str [100];
  815. if (mode == dm_unit)
  816. return "dm_unit";
  817. else if (mode == dm_bypass)
  818. return "dm_bypass";
  819. else if (mode == dm_automaton)
  820. return "dm_automaton";
  821. else if (mode == dm_excl)
  822. return "dm_excl";
  823. else if (mode == dm_presence)
  824. return "dm_presence";
  825. else if (mode == dm_absence)
  826. return "dm_absence";
  827. else if (mode == dm_reserv)
  828. return "dm_reserv";
  829. else if (mode == dm_insn_reserv)
  830. return "dm_insn_reserv";
  831. else
  832. sprintf (str, "unknown (%d)", (int) mode);
  833. return str;
  834. }
  835. /* The function prints message about unexpected declaration and finish
  836. the program. */
  837. static void
  838. decl_mode_check_failed (enum decl_mode mode, const char *expected_mode_str,
  839. const char *file, int line, const char *func)
  840. {
  841. fprintf
  842. (stderr,
  843. "\n%s: %d: error in %s: DECL check: expected decl %s, have %s\n",
  844. file, line, func, expected_mode_str, decl_name (mode));
  845. exit (1);
  846. }
  847. #define REGEXP_UNIT(r) __extension__ \
  848. (({ struct regexp *const _regexp = (r); \
  849. if (_regexp->mode != rm_unit) \
  850. regexp_mode_check_failed (_regexp->mode, "rm_unit", \
  851. __FILE__, __LINE__, __FUNCTION__); \
  852. &(_regexp)->regexp.unit; }))
  853. #define REGEXP_RESERV(r) __extension__ \
  854. (({ struct regexp *const _regexp = (r); \
  855. if (_regexp->mode != rm_reserv) \
  856. regexp_mode_check_failed (_regexp->mode, "rm_reserv", \
  857. __FILE__, __LINE__, __FUNCTION__); \
  858. &(_regexp)->regexp.reserv; }))
  859. #define REGEXP_SEQUENCE(r) __extension__ \
  860. (({ struct regexp *const _regexp = (r); \
  861. if (_regexp->mode != rm_sequence) \
  862. regexp_mode_check_failed (_regexp->mode, "rm_sequence", \
  863. __FILE__, __LINE__, __FUNCTION__); \
  864. &(_regexp)->regexp.sequence; }))
  865. #define REGEXP_REPEAT(r) __extension__ \
  866. (({ struct regexp *const _regexp = (r); \
  867. if (_regexp->mode != rm_repeat) \
  868. regexp_mode_check_failed (_regexp->mode, "rm_repeat", \
  869. __FILE__, __LINE__, __FUNCTION__); \
  870. &(_regexp)->regexp.repeat; }))
  871. #define REGEXP_ALLOF(r) __extension__ \
  872. (({ struct regexp *const _regexp = (r); \
  873. if (_regexp->mode != rm_allof) \
  874. regexp_mode_check_failed (_regexp->mode, "rm_allof", \
  875. __FILE__, __LINE__, __FUNCTION__); \
  876. &(_regexp)->regexp.allof; }))
  877. #define REGEXP_ONEOF(r) __extension__ \
  878. (({ struct regexp *const _regexp = (r); \
  879. if (_regexp->mode != rm_oneof) \
  880. regexp_mode_check_failed (_regexp->mode, "rm_oneof", \
  881. __FILE__, __LINE__, __FUNCTION__); \
  882. &(_regexp)->regexp.oneof; }))
  883. static const char *regexp_name (enum regexp_mode);
  884. static void regexp_mode_check_failed (enum regexp_mode, const char *,
  885. const char *, int,
  886. const char *) ATTRIBUTE_NORETURN;
  887. /* Return string representation of regexp mode MODE. */
  888. static const char *
  889. regexp_name (enum regexp_mode mode)
  890. {
  891. switch (mode)
  892. {
  893. case rm_unit:
  894. return "rm_unit";
  895. case rm_reserv:
  896. return "rm_reserv";
  897. case rm_nothing:
  898. return "rm_nothing";
  899. case rm_sequence:
  900. return "rm_sequence";
  901. case rm_repeat:
  902. return "rm_repeat";
  903. case rm_allof:
  904. return "rm_allof";
  905. case rm_oneof:
  906. return "rm_oneof";
  907. default:
  908. gcc_unreachable ();
  909. }
  910. }
  911. /* The function prints message about unexpected regexp and finish the
  912. program. */
  913. static void
  914. regexp_mode_check_failed (enum regexp_mode mode,
  915. const char *expected_mode_str,
  916. const char *file, int line, const char *func)
  917. {
  918. fprintf
  919. (stderr,
  920. "\n%s: %d: error in %s: REGEXP check: expected decl %s, have %s\n",
  921. file, line, func, expected_mode_str, regexp_name (mode));
  922. exit (1);
  923. }
  924. #else /* #if defined ENABLE_RTL_CHECKING && (GCC_VERSION >= 2007) */
  925. #define DECL_UNIT(d) (&(d)->decl.unit)
  926. #define DECL_BYPASS(d) (&(d)->decl.bypass)
  927. #define DECL_AUTOMATON(d) (&(d)->decl.automaton)
  928. #define DECL_EXCL(d) (&(d)->decl.excl)
  929. #define DECL_PRESENCE(d) (&(d)->decl.presence)
  930. #define DECL_ABSENCE(d) (&(d)->decl.absence)
  931. #define DECL_RESERV(d) (&(d)->decl.reserv)
  932. #define DECL_INSN_RESERV(d) (&(d)->decl.insn_reserv)
  933. #define REGEXP_UNIT(r) (&(r)->regexp.unit)
  934. #define REGEXP_RESERV(r) (&(r)->regexp.reserv)
  935. #define REGEXP_SEQUENCE(r) (&(r)->regexp.sequence)
  936. #define REGEXP_REPEAT(r) (&(r)->regexp.repeat)
  937. #define REGEXP_ALLOF(r) (&(r)->regexp.allof)
  938. #define REGEXP_ONEOF(r) (&(r)->regexp.oneof)
  939. #endif /* #if defined ENABLE_RTL_CHECKING && (GCC_VERSION >= 2007) */
  940. #define XCREATENODE(T) ((T *) create_node (sizeof (T)))
  941. #define XCREATENODEVEC(T, N) ((T *) create_node (sizeof (T) * (N)))
  942. #define XCREATENODEVAR(T, S) ((T *) create_node ((S)))
  943. #define XCOPYNODE(T, P) ((T *) copy_node ((P), sizeof (T)))
  944. #define XCOPYNODEVEC(T, P, N) ((T *) copy_node ((P), sizeof (T) * (N)))
  945. #define XCOPYNODEVAR(T, P, S) ((T *) copy_node ((P), (S)))
  946. /* Create IR structure (node). */
  947. static void *
  948. create_node (size_t size)
  949. {
  950. void *result;
  951. obstack_blank (&irp, size);
  952. result = obstack_base (&irp);
  953. obstack_finish (&irp);
  954. /* Default values of members are NULL and zero. */
  955. memset (result, 0, size);
  956. return result;
  957. }
  958. /* Copy IR structure (node). */
  959. static void *
  960. copy_node (const void *from, size_t size)
  961. {
  962. void *const result = create_node (size);
  963. memcpy (result, from, size);
  964. return result;
  965. }
  966. /* The function checks that NAME does not contain quotes (`"'). */
  967. static const char *
  968. check_name (const char * name, pos_t pos ATTRIBUTE_UNUSED)
  969. {
  970. const char *str;
  971. for (str = name; *str != '\0'; str++)
  972. if (*str == '\"')
  973. error ("Name `%s' contains quotes", name);
  974. return name;
  975. }
  976. /* Pointers to all declarations during IR generation are stored in the
  977. following. */
  978. static vec<decl_t> decls;
  979. /* Given a pointer to a (char *) and a separator, return an alloc'ed
  980. string containing the next separated element, taking parentheses
  981. into account if PAR_FLAG has nonzero value. Advance the pointer to
  982. after the string scanned, or the end-of-string. Return NULL if at
  983. end of string. */
  984. static char *
  985. next_sep_el (const char **pstr, int sep, int par_flag)
  986. {
  987. char *out_str;
  988. const char *p;
  989. int pars_num;
  990. int n_spaces;
  991. /* Remove leading whitespaces. */
  992. while (ISSPACE ((int) **pstr))
  993. (*pstr)++;
  994. if (**pstr == '\0')
  995. return NULL;
  996. n_spaces = 0;
  997. for (pars_num = 0, p = *pstr; *p != '\0'; p++)
  998. {
  999. if (par_flag && *p == '(')
  1000. pars_num++;
  1001. else if (par_flag && *p == ')')
  1002. pars_num--;
  1003. else if (pars_num == 0 && *p == sep)
  1004. break;
  1005. if (pars_num == 0 && ISSPACE ((int) *p))
  1006. n_spaces++;
  1007. else
  1008. {
  1009. for (; n_spaces != 0; n_spaces--)
  1010. obstack_1grow (&irp, p [-n_spaces]);
  1011. obstack_1grow (&irp, *p);
  1012. }
  1013. }
  1014. obstack_1grow (&irp, '\0');
  1015. out_str = (char *) obstack_base (&irp);
  1016. obstack_finish (&irp);
  1017. *pstr = p;
  1018. if (**pstr == sep)
  1019. (*pstr)++;
  1020. return out_str;
  1021. }
  1022. /* Given a string and a separator, return the number of separated
  1023. elements in it, taking parentheses into account if PAR_FLAG has
  1024. nonzero value. Return 0 for the null string, -1 if parentheses is
  1025. not balanced. */
  1026. static int
  1027. n_sep_els (const char *s, int sep, int par_flag)
  1028. {
  1029. int n;
  1030. int pars_num;
  1031. if (*s == '\0')
  1032. return 0;
  1033. for (pars_num = 0, n = 1; *s; s++)
  1034. if (par_flag && *s == '(')
  1035. pars_num++;
  1036. else if (par_flag && *s == ')')
  1037. pars_num--;
  1038. else if (pars_num == 0 && *s == sep)
  1039. n++;
  1040. return (pars_num != 0 ? -1 : n);
  1041. }
  1042. /* Given a string and a separator, return vector of strings which are
  1043. elements in the string and number of elements through els_num.
  1044. Take parentheses into account if PAREN_P has nonzero value. The
  1045. function also inserts the end marker NULL at the end of vector.
  1046. Return 0 for the null string, -1 if parentheses are not balanced. */
  1047. static char **
  1048. get_str_vect (const char *str, int *els_num, int sep, int paren_p)
  1049. {
  1050. int i;
  1051. char **vect;
  1052. const char **pstr;
  1053. char *trail;
  1054. *els_num = n_sep_els (str, sep, paren_p);
  1055. if (*els_num <= 0)
  1056. return NULL;
  1057. obstack_blank (&irp, sizeof (char *) * (*els_num + 1));
  1058. vect = (char **) obstack_base (&irp);
  1059. obstack_finish (&irp);
  1060. pstr = &str;
  1061. for (i = 0; i < *els_num; i++)
  1062. vect [i] = next_sep_el (pstr, sep, paren_p);
  1063. trail = next_sep_el (pstr, sep, paren_p);
  1064. gcc_assert (!trail);
  1065. vect [i] = NULL;
  1066. return vect;
  1067. }
  1068. /* Process a DEFINE_CPU_UNIT.
  1069. This gives information about a unit contained in CPU. We fill a
  1070. struct unit_decl with information used later by `expand_automata'. */
  1071. static void
  1072. gen_cpu_unit (rtx def)
  1073. {
  1074. decl_t decl;
  1075. char **str_cpu_units;
  1076. int vect_length;
  1077. int i;
  1078. str_cpu_units = get_str_vect (XSTR (def, 0), &vect_length, ',', FALSE);
  1079. if (str_cpu_units == NULL)
  1080. fatal ("invalid string `%s' in define_cpu_unit", XSTR (def, 0));
  1081. for (i = 0; i < vect_length; i++)
  1082. {
  1083. decl = XCREATENODE (struct decl);
  1084. decl->mode = dm_unit;
  1085. decl->pos = 0;
  1086. DECL_UNIT (decl)->name = check_name (str_cpu_units [i], decl->pos);
  1087. DECL_UNIT (decl)->automaton_name = XSTR (def, 1);
  1088. DECL_UNIT (decl)->query_p = 0;
  1089. DECL_UNIT (decl)->min_occ_cycle_num = -1;
  1090. DECL_UNIT (decl)->in_set_p = 0;
  1091. decls.safe_push (decl);
  1092. }
  1093. }
  1094. /* Process a DEFINE_QUERY_CPU_UNIT.
  1095. This gives information about a unit contained in CPU. We fill a
  1096. struct unit_decl with information used later by `expand_automata'. */
  1097. static void
  1098. gen_query_cpu_unit (rtx def)
  1099. {
  1100. decl_t decl;
  1101. char **str_cpu_units;
  1102. int vect_length;
  1103. int i;
  1104. str_cpu_units = get_str_vect (XSTR (def, 0), &vect_length, ',',
  1105. FALSE);
  1106. if (str_cpu_units == NULL)
  1107. fatal ("invalid string `%s' in define_query_cpu_unit", XSTR (def, 0));
  1108. for (i = 0; i < vect_length; i++)
  1109. {
  1110. decl = XCREATENODE (struct decl);
  1111. decl->mode = dm_unit;
  1112. decl->pos = 0;
  1113. DECL_UNIT (decl)->name = check_name (str_cpu_units [i], decl->pos);
  1114. DECL_UNIT (decl)->automaton_name = XSTR (def, 1);
  1115. DECL_UNIT (decl)->query_p = 1;
  1116. decls.safe_push (decl);
  1117. }
  1118. }
  1119. /* Process a DEFINE_BYPASS.
  1120. This gives information about a unit contained in the CPU. We fill
  1121. in a struct bypass_decl with information used later by
  1122. `expand_automata'. */
  1123. static void
  1124. gen_bypass (rtx def)
  1125. {
  1126. decl_t decl;
  1127. char **out_patterns;
  1128. int out_length;
  1129. char **in_patterns;
  1130. int in_length;
  1131. int i, j;
  1132. out_patterns = get_str_vect (XSTR (def, 1), &out_length, ',', FALSE);
  1133. if (out_patterns == NULL)
  1134. fatal ("invalid string `%s' in define_bypass", XSTR (def, 1));
  1135. in_patterns = get_str_vect (XSTR (def, 2), &in_length, ',', FALSE);
  1136. if (in_patterns == NULL)
  1137. fatal ("invalid string `%s' in define_bypass", XSTR (def, 2));
  1138. for (i = 0; i < out_length; i++)
  1139. for (j = 0; j < in_length; j++)
  1140. {
  1141. decl = XCREATENODE (struct decl);
  1142. decl->mode = dm_bypass;
  1143. decl->pos = 0;
  1144. DECL_BYPASS (decl)->latency = XINT (def, 0);
  1145. DECL_BYPASS (decl)->out_pattern = out_patterns[i];
  1146. DECL_BYPASS (decl)->in_pattern = in_patterns[j];
  1147. DECL_BYPASS (decl)->bypass_guard_name = XSTR (def, 3);
  1148. decls.safe_push (decl);
  1149. }
  1150. }
  1151. /* Process an EXCLUSION_SET.
  1152. This gives information about a cpu unit conflicts. We fill a
  1153. struct excl_rel_decl (excl) with information used later by
  1154. `expand_automata'. */
  1155. static void
  1156. gen_excl_set (rtx def)
  1157. {
  1158. decl_t decl;
  1159. char **first_str_cpu_units;
  1160. char **second_str_cpu_units;
  1161. int first_vect_length;
  1162. int length;
  1163. int i;
  1164. first_str_cpu_units
  1165. = get_str_vect (XSTR (def, 0), &first_vect_length, ',', FALSE);
  1166. if (first_str_cpu_units == NULL)
  1167. fatal ("invalid first string `%s' in exclusion_set", XSTR (def, 0));
  1168. second_str_cpu_units = get_str_vect (XSTR (def, 1), &length, ',',
  1169. FALSE);
  1170. if (second_str_cpu_units == NULL)
  1171. fatal ("invalid second string `%s' in exclusion_set", XSTR (def, 1));
  1172. length += first_vect_length;
  1173. decl = XCREATENODEVAR (struct decl, sizeof (struct decl) + (length - 1) * sizeof (char *));
  1174. decl->mode = dm_excl;
  1175. decl->pos = 0;
  1176. DECL_EXCL (decl)->all_names_num = length;
  1177. DECL_EXCL (decl)->first_list_length = first_vect_length;
  1178. for (i = 0; i < length; i++)
  1179. if (i < first_vect_length)
  1180. DECL_EXCL (decl)->names [i] = first_str_cpu_units [i];
  1181. else
  1182. DECL_EXCL (decl)->names [i]
  1183. = second_str_cpu_units [i - first_vect_length];
  1184. decls.safe_push (decl);
  1185. }
  1186. /* Process a PRESENCE_SET, a FINAL_PRESENCE_SET, an ABSENCE_SET,
  1187. FINAL_ABSENCE_SET (it is depended on PRESENCE_P and FINAL_P).
  1188. This gives information about a cpu unit reservation requirements.
  1189. We fill a struct unit_pattern_rel_decl with information used later
  1190. by `expand_automata'. */
  1191. static void
  1192. gen_presence_absence_set (rtx def, int presence_p, int final_p)
  1193. {
  1194. decl_t decl;
  1195. char **str_cpu_units;
  1196. char **str_pattern_lists;
  1197. char ***str_patterns;
  1198. int cpu_units_length;
  1199. int length;
  1200. int patterns_length;
  1201. int i;
  1202. str_cpu_units = get_str_vect (XSTR (def, 0), &cpu_units_length, ',',
  1203. FALSE);
  1204. if (str_cpu_units == NULL)
  1205. fatal ((presence_p
  1206. ? (final_p
  1207. ? "invalid first string `%s' in final_presence_set"
  1208. : "invalid first string `%s' in presence_set")
  1209. : (final_p
  1210. ? "invalid first string `%s' in final_absence_set"
  1211. : "invalid first string `%s' in absence_set")),
  1212. XSTR (def, 0));
  1213. str_pattern_lists = get_str_vect (XSTR (def, 1),
  1214. &patterns_length, ',', FALSE);
  1215. if (str_pattern_lists == NULL)
  1216. fatal ((presence_p
  1217. ? (final_p
  1218. ? "invalid second string `%s' in final_presence_set"
  1219. : "invalid second string `%s' in presence_set")
  1220. : (final_p
  1221. ? "invalid second string `%s' in final_absence_set"
  1222. : "invalid second string `%s' in absence_set")), XSTR (def, 1));
  1223. str_patterns = XOBNEWVEC (&irp, char **, patterns_length);
  1224. for (i = 0; i < patterns_length; i++)
  1225. {
  1226. str_patterns [i] = get_str_vect (str_pattern_lists [i],
  1227. &length, ' ', FALSE);
  1228. gcc_assert (str_patterns [i]);
  1229. }
  1230. decl = XCREATENODE (struct decl);
  1231. decl->pos = 0;
  1232. if (presence_p)
  1233. {
  1234. decl->mode = dm_presence;
  1235. DECL_PRESENCE (decl)->names_num = cpu_units_length;
  1236. DECL_PRESENCE (decl)->names = str_cpu_units;
  1237. DECL_PRESENCE (decl)->patterns = str_patterns;
  1238. DECL_PRESENCE (decl)->patterns_num = patterns_length;
  1239. DECL_PRESENCE (decl)->final_p = final_p;
  1240. }
  1241. else
  1242. {
  1243. decl->mode = dm_absence;
  1244. DECL_ABSENCE (decl)->names_num = cpu_units_length;
  1245. DECL_ABSENCE (decl)->names = str_cpu_units;
  1246. DECL_ABSENCE (decl)->patterns = str_patterns;
  1247. DECL_ABSENCE (decl)->patterns_num = patterns_length;
  1248. DECL_ABSENCE (decl)->final_p = final_p;
  1249. }
  1250. decls.safe_push (decl);
  1251. }
  1252. /* Process a PRESENCE_SET.
  1253. This gives information about a cpu unit reservation requirements.
  1254. We fill a struct unit_pattern_rel_decl (presence) with information
  1255. used later by `expand_automata'. */
  1256. static void
  1257. gen_presence_set (rtx def)
  1258. {
  1259. gen_presence_absence_set (def, TRUE, FALSE);
  1260. }
  1261. /* Process a FINAL_PRESENCE_SET.
  1262. This gives information about a cpu unit reservation requirements.
  1263. We fill a struct unit_pattern_rel_decl (presence) with information
  1264. used later by `expand_automata'. */
  1265. static void
  1266. gen_final_presence_set (rtx def)
  1267. {
  1268. gen_presence_absence_set (def, TRUE, TRUE);
  1269. }
  1270. /* Process an ABSENCE_SET.
  1271. This gives information about a cpu unit reservation requirements.
  1272. We fill a struct unit_pattern_rel_decl (absence) with information
  1273. used later by `expand_automata'. */
  1274. static void
  1275. gen_absence_set (rtx def)
  1276. {
  1277. gen_presence_absence_set (def, FALSE, FALSE);
  1278. }
  1279. /* Process a FINAL_ABSENCE_SET.
  1280. This gives information about a cpu unit reservation requirements.
  1281. We fill a struct unit_pattern_rel_decl (absence) with information
  1282. used later by `expand_automata'. */
  1283. static void
  1284. gen_final_absence_set (rtx def)
  1285. {
  1286. gen_presence_absence_set (def, FALSE, TRUE);
  1287. }
  1288. /* Process a DEFINE_AUTOMATON.
  1289. This gives information about a finite state automaton used for
  1290. recognizing pipeline hazards. We fill a struct automaton_decl
  1291. with information used later by `expand_automata'. */
  1292. static void
  1293. gen_automaton (rtx def)
  1294. {
  1295. decl_t decl;
  1296. char **str_automata;
  1297. int vect_length;
  1298. int i;
  1299. str_automata = get_str_vect (XSTR (def, 0), &vect_length, ',', FALSE);
  1300. if (str_automata == NULL)
  1301. fatal ("invalid string `%s' in define_automaton", XSTR (def, 0));
  1302. for (i = 0; i < vect_length; i++)
  1303. {
  1304. decl = XCREATENODE (struct decl);
  1305. decl->mode = dm_automaton;
  1306. decl->pos = 0;
  1307. DECL_AUTOMATON (decl)->name = check_name (str_automata [i], decl->pos);
  1308. decls.safe_push (decl);
  1309. }
  1310. }
  1311. /* Process an AUTOMATA_OPTION.
  1312. This gives information how to generate finite state automaton used
  1313. for recognizing pipeline hazards. */
  1314. static void
  1315. gen_automata_option (rtx def)
  1316. {
  1317. if (strcmp (XSTR (def, 0), NO_MINIMIZATION_OPTION + 1) == 0)
  1318. no_minimization_flag = 1;
  1319. else if (strcmp (XSTR (def, 0), TIME_OPTION + 1) == 0)
  1320. time_flag = 1;
  1321. else if (strcmp (XSTR (def, 0), STATS_OPTION + 1) == 0)
  1322. stats_flag = 1;
  1323. else if (strcmp (XSTR (def, 0), V_OPTION + 1) == 0)
  1324. v_flag = 1;
  1325. else if (strcmp (XSTR (def, 0), W_OPTION + 1) == 0)
  1326. w_flag = 1;
  1327. else if (strcmp (XSTR (def, 0), NDFA_OPTION + 1) == 0)
  1328. ndfa_flag = 1;
  1329. else if (strcmp (XSTR (def, 0), COLLAPSE_OPTION + 1) == 0)
  1330. collapse_flag = 1;
  1331. else if (strcmp (XSTR (def, 0), NO_COMB_OPTION + 1) == 0)
  1332. no_comb_flag = 1;
  1333. else if (strcmp (XSTR (def, 0), PROGRESS_OPTION + 1) == 0)
  1334. progress_flag = 1;
  1335. else
  1336. fatal ("invalid option `%s' in automata_option", XSTR (def, 0));
  1337. }
  1338. /* Name in reservation to denote absence reservation. */
  1339. #define NOTHING_NAME "nothing"
  1340. /* The following string contains original reservation string being
  1341. parsed. */
  1342. static const char *reserv_str;
  1343. /* Parse an element in STR. */
  1344. static regexp_t
  1345. gen_regexp_el (const char *str)
  1346. {
  1347. regexp_t regexp;
  1348. char *dstr;
  1349. int len;
  1350. if (*str == '(')
  1351. {
  1352. len = strlen (str);
  1353. if (str [len - 1] != ')')
  1354. fatal ("garbage after ) in reservation `%s'", reserv_str);
  1355. dstr = XALLOCAVAR (char, len - 1);
  1356. memcpy (dstr, str + 1, len - 2);
  1357. dstr [len-2] = '\0';
  1358. regexp = gen_regexp_sequence (dstr);
  1359. }
  1360. else if (strcmp (str, NOTHING_NAME) == 0)
  1361. {
  1362. regexp = XCREATENODE (struct regexp);
  1363. regexp->mode = rm_nothing;
  1364. }
  1365. else
  1366. {
  1367. regexp = XCREATENODE (struct regexp);
  1368. regexp->mode = rm_unit;
  1369. REGEXP_UNIT (regexp)->name = str;
  1370. }
  1371. return regexp;
  1372. }
  1373. /* Parse construction `repeat' in STR. */
  1374. static regexp_t
  1375. gen_regexp_repeat (const char *str)
  1376. {
  1377. regexp_t regexp;
  1378. regexp_t repeat;
  1379. char **repeat_vect;
  1380. int els_num;
  1381. int i;
  1382. repeat_vect = get_str_vect (str, &els_num, '*', TRUE);
  1383. if (repeat_vect == NULL)
  1384. fatal ("invalid `%s' in reservation `%s'", str, reserv_str);
  1385. if (els_num > 1)
  1386. {
  1387. regexp = gen_regexp_el (repeat_vect [0]);
  1388. for (i = 1; i < els_num; i++)
  1389. {
  1390. repeat = XCREATENODE (struct regexp);
  1391. repeat->mode = rm_repeat;
  1392. REGEXP_REPEAT (repeat)->regexp = regexp;
  1393. REGEXP_REPEAT (repeat)->repeat_num = atoi (repeat_vect [i]);
  1394. if (REGEXP_REPEAT (repeat)->repeat_num <= 1)
  1395. fatal ("repetition `%s' <= 1 in reservation `%s'",
  1396. str, reserv_str);
  1397. regexp = repeat;
  1398. }
  1399. return regexp;
  1400. }
  1401. else
  1402. return gen_regexp_el (repeat_vect[0]);
  1403. }
  1404. /* Parse reservation STR which possibly contains separator '+'. */
  1405. static regexp_t
  1406. gen_regexp_allof (const char *str)
  1407. {
  1408. regexp_t allof;
  1409. char **allof_vect;
  1410. int els_num;
  1411. int i;
  1412. allof_vect = get_str_vect (str, &els_num, '+', TRUE);
  1413. if (allof_vect == NULL)
  1414. fatal ("invalid `%s' in reservation `%s'", str, reserv_str);
  1415. if (els_num > 1)
  1416. {
  1417. allof = XCREATENODEVAR (struct regexp, sizeof (struct regexp)
  1418. + sizeof (regexp_t) * (els_num - 1));
  1419. allof->mode = rm_allof;
  1420. REGEXP_ALLOF (allof)->regexps_num = els_num;
  1421. for (i = 0; i < els_num; i++)
  1422. REGEXP_ALLOF (allof)->regexps [i] = gen_regexp_repeat (allof_vect [i]);
  1423. return allof;
  1424. }
  1425. else
  1426. return gen_regexp_repeat (allof_vect[0]);
  1427. }
  1428. /* Parse reservation STR which possibly contains separator '|'. */
  1429. static regexp_t
  1430. gen_regexp_oneof (const char *str)
  1431. {
  1432. regexp_t oneof;
  1433. char **oneof_vect;
  1434. int els_num;
  1435. int i;
  1436. oneof_vect = get_str_vect (str, &els_num, '|', TRUE);
  1437. if (oneof_vect == NULL)
  1438. fatal ("invalid `%s' in reservation `%s'", str, reserv_str);
  1439. if (els_num > 1)
  1440. {
  1441. oneof = XCREATENODEVAR (struct regexp, sizeof (struct regexp)
  1442. + sizeof (regexp_t) * (els_num - 1));
  1443. oneof->mode = rm_oneof;
  1444. REGEXP_ONEOF (oneof)->regexps_num = els_num;
  1445. for (i = 0; i < els_num; i++)
  1446. REGEXP_ONEOF (oneof)->regexps [i] = gen_regexp_allof (oneof_vect [i]);
  1447. return oneof;
  1448. }
  1449. else
  1450. return gen_regexp_allof (oneof_vect[0]);
  1451. }
  1452. /* Parse reservation STR which possibly contains separator ','. */
  1453. static regexp_t
  1454. gen_regexp_sequence (const char *str)
  1455. {
  1456. regexp_t sequence;
  1457. char **sequence_vect;
  1458. int els_num;
  1459. int i;
  1460. sequence_vect = get_str_vect (str, &els_num, ',', TRUE);
  1461. if (els_num == -1)
  1462. fatal ("unbalanced parentheses in reservation `%s'", str);
  1463. if (sequence_vect == NULL)
  1464. fatal ("invalid reservation `%s'", str);
  1465. if (els_num > 1)
  1466. {
  1467. sequence = XCREATENODEVAR (struct regexp, sizeof (struct regexp)
  1468. + sizeof (regexp_t) * (els_num - 1));
  1469. sequence->mode = rm_sequence;
  1470. REGEXP_SEQUENCE (sequence)->regexps_num = els_num;
  1471. for (i = 0; i < els_num; i++)
  1472. REGEXP_SEQUENCE (sequence)->regexps [i]
  1473. = gen_regexp_oneof (sequence_vect [i]);
  1474. return sequence;
  1475. }
  1476. else
  1477. return gen_regexp_oneof (sequence_vect[0]);
  1478. }
  1479. /* Parse construction reservation STR. */
  1480. static regexp_t
  1481. gen_regexp (const char *str)
  1482. {
  1483. reserv_str = str;
  1484. return gen_regexp_sequence (str);
  1485. }
  1486. /* Process a DEFINE_RESERVATION.
  1487. This gives information about a reservation of cpu units. We fill
  1488. in a struct reserv_decl with information used later by
  1489. `expand_automata'. */
  1490. static void
  1491. gen_reserv (rtx def)
  1492. {
  1493. decl_t decl;
  1494. decl = XCREATENODE (struct decl);
  1495. decl->mode = dm_reserv;
  1496. decl->pos = 0;
  1497. DECL_RESERV (decl)->name = check_name (XSTR (def, 0), decl->pos);
  1498. DECL_RESERV (decl)->regexp = gen_regexp (XSTR (def, 1));
  1499. decls.safe_push (decl);
  1500. }
  1501. /* Process a DEFINE_INSN_RESERVATION.
  1502. This gives information about the reservation of cpu units by an
  1503. insn. We fill a struct insn_reserv_decl with information used
  1504. later by `expand_automata'. */
  1505. static void
  1506. gen_insn_reserv (rtx def)
  1507. {
  1508. decl_t decl;
  1509. decl = XCREATENODE (struct decl);
  1510. decl->mode = dm_insn_reserv;
  1511. decl->pos = 0;
  1512. DECL_INSN_RESERV (decl)->name
  1513. = check_name (XSTR (def, 0), decl->pos);
  1514. DECL_INSN_RESERV (decl)->default_latency = XINT (def, 1);
  1515. DECL_INSN_RESERV (decl)->condexp = XEXP (def, 2);
  1516. DECL_INSN_RESERV (decl)->regexp = gen_regexp (XSTR (def, 3));
  1517. decls.safe_push (decl);
  1518. }
  1519. /* The function evaluates hash value (0..UINT_MAX) of string. */
  1520. static unsigned
  1521. string_hash (const char *string)
  1522. {
  1523. unsigned result, i;
  1524. for (result = i = 0;*string++ != '\0'; i++)
  1525. result += ((unsigned char) *string << (i % CHAR_BIT));
  1526. return result;
  1527. }
  1528. /* This page contains abstract data `table of automaton declarations'.
  1529. Elements of the table is nodes representing automaton declarations.
  1530. Key of the table elements is name of given automaton. Remember
  1531. that automaton names have own space. */
  1532. /* The function evaluates hash value of an automaton declaration. The
  1533. function is used by abstract data `hashtab'. The function returns
  1534. hash value (0..UINT_MAX) of given automaton declaration. */
  1535. static hashval_t
  1536. automaton_decl_hash (const void *automaton_decl)
  1537. {
  1538. const_decl_t const decl = (const_decl_t) automaton_decl;
  1539. gcc_assert (decl->mode != dm_automaton
  1540. || DECL_AUTOMATON (decl)->name);
  1541. return string_hash (DECL_AUTOMATON (decl)->name);
  1542. }
  1543. /* The function tests automaton declarations on equality of their
  1544. keys. The function is used by abstract data `hashtab'. The
  1545. function returns 1 if the declarations have the same key, 0
  1546. otherwise. */
  1547. static int
  1548. automaton_decl_eq_p (const void* automaton_decl_1,
  1549. const void* automaton_decl_2)
  1550. {
  1551. const_decl_t const decl1 = (const_decl_t) automaton_decl_1;
  1552. const_decl_t const decl2 = (const_decl_t) automaton_decl_2;
  1553. gcc_assert (decl1->mode == dm_automaton
  1554. && DECL_AUTOMATON (decl1)->name
  1555. && decl2->mode == dm_automaton
  1556. && DECL_AUTOMATON (decl2)->name);
  1557. return strcmp (DECL_AUTOMATON (decl1)->name,
  1558. DECL_AUTOMATON (decl2)->name) == 0;
  1559. }
  1560. /* The automaton declaration table itself is represented by the
  1561. following variable. */
  1562. static htab_t automaton_decl_table;
  1563. /* The function inserts automaton declaration into the table. The
  1564. function does nothing if an automaton declaration with the same key
  1565. exists already in the table. The function returns automaton
  1566. declaration node in the table with the same key as given automaton
  1567. declaration node. */
  1568. static decl_t
  1569. insert_automaton_decl (decl_t automaton_decl)
  1570. {
  1571. void **entry_ptr;
  1572. entry_ptr = htab_find_slot (automaton_decl_table, automaton_decl, INSERT);
  1573. if (*entry_ptr == NULL)
  1574. *entry_ptr = (void *) automaton_decl;
  1575. return (decl_t) *entry_ptr;
  1576. }
  1577. /* The following variable value is node representing automaton
  1578. declaration. The node used for searching automaton declaration
  1579. with given name. */
  1580. static struct decl work_automaton_decl;
  1581. /* The function searches for automaton declaration in the table with
  1582. the same key as node representing name of the automaton
  1583. declaration. The function returns node found in the table, NULL if
  1584. such node does not exist in the table. */
  1585. static decl_t
  1586. find_automaton_decl (const char *name)
  1587. {
  1588. void *entry;
  1589. work_automaton_decl.mode = dm_automaton;
  1590. DECL_AUTOMATON (&work_automaton_decl)->name = name;
  1591. entry = htab_find (automaton_decl_table, &work_automaton_decl);
  1592. return (decl_t) entry;
  1593. }
  1594. /* The function creates empty automaton declaration table and node
  1595. representing automaton declaration and used for searching automaton
  1596. declaration with given name. The function must be called only once
  1597. before any work with the automaton declaration table. */
  1598. static void
  1599. initiate_automaton_decl_table (void)
  1600. {
  1601. work_automaton_decl.mode = dm_automaton;
  1602. automaton_decl_table = htab_create (10, automaton_decl_hash,
  1603. automaton_decl_eq_p, (htab_del) 0);
  1604. }
  1605. /* The function deletes the automaton declaration table. Only call of
  1606. function `initiate_automaton_decl_table' is possible immediately
  1607. after this function call. */
  1608. static void
  1609. finish_automaton_decl_table (void)
  1610. {
  1611. htab_delete (automaton_decl_table);
  1612. }
  1613. /* This page contains abstract data `table of insn declarations'.
  1614. Elements of the table is nodes representing insn declarations. Key
  1615. of the table elements is name of given insn (in corresponding
  1616. define_insn_reservation). Remember that insn names have own
  1617. space. */
  1618. /* The function evaluates hash value of an insn declaration. The
  1619. function is used by abstract data `hashtab'. The function returns
  1620. hash value (0..UINT_MAX) of given insn declaration. */
  1621. static hashval_t
  1622. insn_decl_hash (const void *insn_decl)
  1623. {
  1624. const_decl_t const decl = (const_decl_t) insn_decl;
  1625. gcc_assert (decl->mode == dm_insn_reserv
  1626. && DECL_INSN_RESERV (decl)->name);
  1627. return string_hash (DECL_INSN_RESERV (decl)->name);
  1628. }
  1629. /* The function tests insn declarations on equality of their keys.
  1630. The function is used by abstract data `hashtab'. The function
  1631. returns 1 if declarations have the same key, 0 otherwise. */
  1632. static int
  1633. insn_decl_eq_p (const void *insn_decl_1, const void *insn_decl_2)
  1634. {
  1635. const_decl_t const decl1 = (const_decl_t) insn_decl_1;
  1636. const_decl_t const decl2 = (const_decl_t) insn_decl_2;
  1637. gcc_assert (decl1->mode == dm_insn_reserv
  1638. && DECL_INSN_RESERV (decl1)->name
  1639. && decl2->mode == dm_insn_reserv
  1640. && DECL_INSN_RESERV (decl2)->name);
  1641. return strcmp (DECL_INSN_RESERV (decl1)->name,
  1642. DECL_INSN_RESERV (decl2)->name) == 0;
  1643. }
  1644. /* The insn declaration table itself is represented by the following
  1645. variable. The table does not contain insn reservation
  1646. declarations. */
  1647. static htab_t insn_decl_table;
  1648. /* The function inserts insn declaration into the table. The function
  1649. does nothing if an insn declaration with the same key exists
  1650. already in the table. The function returns insn declaration node
  1651. in the table with the same key as given insn declaration node. */
  1652. static decl_t
  1653. insert_insn_decl (decl_t insn_decl)
  1654. {
  1655. void **entry_ptr;
  1656. entry_ptr = htab_find_slot (insn_decl_table, insn_decl, INSERT);
  1657. if (*entry_ptr == NULL)
  1658. *entry_ptr = (void *) insn_decl;
  1659. return (decl_t) *entry_ptr;
  1660. }
  1661. /* The following variable value is node representing insn reservation
  1662. declaration. The node used for searching insn reservation
  1663. declaration with given name. */
  1664. static struct decl work_insn_decl;
  1665. /* The function searches for insn reservation declaration in the table
  1666. with the same key as node representing name of the insn reservation
  1667. declaration. The function returns node found in the table, NULL if
  1668. such node does not exist in the table. */
  1669. static decl_t
  1670. find_insn_decl (const char *name)
  1671. {
  1672. void *entry;
  1673. work_insn_decl.mode = dm_insn_reserv;
  1674. DECL_INSN_RESERV (&work_insn_decl)->name = name;
  1675. entry = htab_find (insn_decl_table, &work_insn_decl);
  1676. return (decl_t) entry;
  1677. }
  1678. /* The function creates empty insn declaration table and node
  1679. representing insn declaration and used for searching insn
  1680. declaration with given name. The function must be called only once
  1681. before any work with the insn declaration table. */
  1682. static void
  1683. initiate_insn_decl_table (void)
  1684. {
  1685. work_insn_decl.mode = dm_insn_reserv;
  1686. insn_decl_table = htab_create (10, insn_decl_hash, insn_decl_eq_p,
  1687. (htab_del) 0);
  1688. }
  1689. /* The function deletes the insn declaration table. Only call of
  1690. function `initiate_insn_decl_table' is possible immediately after
  1691. this function call. */
  1692. static void
  1693. finish_insn_decl_table (void)
  1694. {
  1695. htab_delete (insn_decl_table);
  1696. }
  1697. /* This page contains abstract data `table of declarations'. Elements
  1698. of the table is nodes representing declarations (of units and
  1699. reservations). Key of the table elements is names of given
  1700. declarations. */
  1701. /* The function evaluates hash value of a declaration. The function
  1702. is used by abstract data `hashtab'. The function returns hash
  1703. value (0..UINT_MAX) of given declaration. */
  1704. static hashval_t
  1705. decl_hash (const void *decl)
  1706. {
  1707. const_decl_t const d = (const_decl_t) decl;
  1708. gcc_assert ((d->mode == dm_unit && DECL_UNIT (d)->name)
  1709. || (d->mode == dm_reserv && DECL_RESERV (d)->name));
  1710. return string_hash (d->mode == dm_unit
  1711. ? DECL_UNIT (d)->name : DECL_RESERV (d)->name);
  1712. }
  1713. /* The function tests declarations on equality of their keys. The
  1714. function is used by abstract data 'hashtab'. The function
  1715. returns 1 if the declarations have the same key, 0 otherwise. */
  1716. static int
  1717. decl_eq_p (const void *decl_1, const void *decl_2)
  1718. {
  1719. const_decl_t const d1 = (const_decl_t) decl_1;
  1720. const_decl_t const d2 = (const_decl_t) decl_2;
  1721. gcc_assert ((d1->mode == dm_unit && DECL_UNIT (d1)->name)
  1722. || (d1->mode == dm_reserv && DECL_RESERV (d1)->name));
  1723. gcc_assert ((d2->mode == dm_unit && DECL_UNIT (d2)->name)
  1724. || (d2->mode == dm_reserv && DECL_RESERV (d2)->name));
  1725. return strcmp ((d1->mode == dm_unit
  1726. ? DECL_UNIT (d1)->name : DECL_RESERV (d1)->name),
  1727. (d2->mode == dm_unit
  1728. ? DECL_UNIT (d2)->name : DECL_RESERV (d2)->name)) == 0;
  1729. }
  1730. /* The declaration table itself is represented by the following
  1731. variable. */
  1732. static htab_t decl_table;
  1733. /* The function inserts declaration into the table. The function does
  1734. nothing if a declaration with the same key exists already in the
  1735. table. The function returns declaration node in the table with the
  1736. same key as given declaration node. */
  1737. static decl_t
  1738. insert_decl (decl_t decl)
  1739. {
  1740. void **entry_ptr;
  1741. entry_ptr = htab_find_slot (decl_table, decl, INSERT);
  1742. if (*entry_ptr == NULL)
  1743. *entry_ptr = (void *) decl;
  1744. return (decl_t) *entry_ptr;
  1745. }
  1746. /* The following variable value is node representing declaration. The
  1747. node used for searching declaration with given name. */
  1748. static struct decl work_decl;
  1749. /* The function searches for declaration in the table with the same
  1750. key as node representing name of the declaration. The function
  1751. returns node found in the table, NULL if such node does not exist
  1752. in the table. */
  1753. static decl_t
  1754. find_decl (const char *name)
  1755. {
  1756. void *entry;
  1757. work_decl.mode = dm_unit;
  1758. DECL_UNIT (&work_decl)->name = name;
  1759. entry = htab_find (decl_table, &work_decl);
  1760. return (decl_t) entry;
  1761. }
  1762. /* The function creates empty declaration table and node representing
  1763. declaration and used for searching declaration with given name.
  1764. The function must be called only once before any work with the
  1765. declaration table. */
  1766. static void
  1767. initiate_decl_table (void)
  1768. {
  1769. work_decl.mode = dm_unit;
  1770. decl_table = htab_create (10, decl_hash, decl_eq_p, (htab_del) 0);
  1771. }
  1772. /* The function deletes the declaration table. Only call of function
  1773. `initiate_declaration_table' is possible immediately after this
  1774. function call. */
  1775. static void
  1776. finish_decl_table (void)
  1777. {
  1778. htab_delete (decl_table);
  1779. }
  1780. /* This page contains checker of pipeline hazard description. */
  1781. /* Checking NAMES in an exclusion clause vector and returning formed
  1782. unit_set_el_list. */
  1783. static unit_set_el_t
  1784. process_excls (char **names, int num, pos_t excl_pos ATTRIBUTE_UNUSED)
  1785. {
  1786. unit_set_el_t el_list;
  1787. unit_set_el_t last_el;
  1788. unit_set_el_t new_el;
  1789. decl_t decl_in_table;
  1790. int i;
  1791. el_list = NULL;
  1792. last_el = NULL;
  1793. for (i = 0; i < num; i++)
  1794. {
  1795. decl_in_table = find_decl (names [i]);
  1796. if (decl_in_table == NULL)
  1797. error ("unit `%s' in exclusion is not declared", names [i]);
  1798. else if (decl_in_table->mode != dm_unit)
  1799. error ("`%s' in exclusion is not unit", names [i]);
  1800. else
  1801. {
  1802. new_el = XCREATENODE (struct unit_set_el);
  1803. new_el->unit_decl = DECL_UNIT (decl_in_table);
  1804. new_el->next_unit_set_el = NULL;
  1805. if (last_el == NULL)
  1806. el_list = last_el = new_el;
  1807. else
  1808. {
  1809. last_el->next_unit_set_el = new_el;
  1810. last_el = last_el->next_unit_set_el;
  1811. }
  1812. }
  1813. }
  1814. return el_list;
  1815. }
  1816. /* The function adds each element from SOURCE_LIST to the exclusion
  1817. list of the each element from DEST_LIST. Checking situation "unit
  1818. excludes itself". */
  1819. static void
  1820. add_excls (unit_set_el_t dest_list, unit_set_el_t source_list,
  1821. pos_t excl_pos ATTRIBUTE_UNUSED)
  1822. {
  1823. unit_set_el_t dst;
  1824. unit_set_el_t src;
  1825. unit_set_el_t curr_el;
  1826. unit_set_el_t prev_el;
  1827. unit_set_el_t copy;
  1828. for (dst = dest_list; dst != NULL; dst = dst->next_unit_set_el)
  1829. for (src = source_list; src != NULL; src = src->next_unit_set_el)
  1830. {
  1831. if (dst->unit_decl == src->unit_decl)
  1832. {
  1833. error ("unit `%s' excludes itself", src->unit_decl->name);
  1834. continue;
  1835. }
  1836. if (dst->unit_decl->automaton_name != NULL
  1837. && src->unit_decl->automaton_name != NULL
  1838. && strcmp (dst->unit_decl->automaton_name,
  1839. src->unit_decl->automaton_name) != 0)
  1840. {
  1841. error ("units `%s' and `%s' in exclusion set belong to different automata",
  1842. src->unit_decl->name, dst->unit_decl->name);
  1843. continue;
  1844. }
  1845. for (curr_el = dst->unit_decl->excl_list, prev_el = NULL;
  1846. curr_el != NULL;
  1847. prev_el = curr_el, curr_el = curr_el->next_unit_set_el)
  1848. if (curr_el->unit_decl == src->unit_decl)
  1849. break;
  1850. if (curr_el == NULL)
  1851. {
  1852. /* Element not found - insert. */
  1853. copy = XCOPYNODE (struct unit_set_el, src);
  1854. copy->next_unit_set_el = NULL;
  1855. if (prev_el == NULL)
  1856. dst->unit_decl->excl_list = copy;
  1857. else
  1858. prev_el->next_unit_set_el = copy;
  1859. }
  1860. }
  1861. }
  1862. /* Checking NAMES in presence/absence clause and returning the
  1863. formed unit_set_el_list. The function is called only after
  1864. processing all exclusion sets. */
  1865. static unit_set_el_t
  1866. process_presence_absence_names (char **names, int num,
  1867. pos_t req_pos ATTRIBUTE_UNUSED,
  1868. int presence_p, int final_p)
  1869. {
  1870. unit_set_el_t el_list;
  1871. unit_set_el_t last_el;
  1872. unit_set_el_t new_el;
  1873. decl_t decl_in_table;
  1874. int i;
  1875. el_list = NULL;
  1876. last_el = NULL;
  1877. for (i = 0; i < num; i++)
  1878. {
  1879. decl_in_table = find_decl (names [i]);
  1880. if (decl_in_table == NULL)
  1881. error ((presence_p
  1882. ? (final_p
  1883. ? "unit `%s' in final presence set is not declared"
  1884. : "unit `%s' in presence set is not declared")
  1885. : (final_p
  1886. ? "unit `%s' in final absence set is not declared"
  1887. : "unit `%s' in absence set is not declared")), names [i]);
  1888. else if (decl_in_table->mode != dm_unit)
  1889. error ((presence_p
  1890. ? (final_p
  1891. ? "`%s' in final presence set is not unit"
  1892. : "`%s' in presence set is not unit")
  1893. : (final_p
  1894. ? "`%s' in final absence set is not unit"
  1895. : "`%s' in absence set is not unit")), names [i]);
  1896. else
  1897. {
  1898. new_el = XCREATENODE (struct unit_set_el);
  1899. new_el->unit_decl = DECL_UNIT (decl_in_table);
  1900. new_el->next_unit_set_el = NULL;
  1901. if (last_el == NULL)
  1902. el_list = last_el = new_el;
  1903. else
  1904. {
  1905. last_el->next_unit_set_el = new_el;
  1906. last_el = last_el->next_unit_set_el;
  1907. }
  1908. }
  1909. }
  1910. return el_list;
  1911. }
  1912. /* Checking NAMES in patterns of a presence/absence clause and
  1913. returning the formed pattern_set_el_list. The function is called
  1914. only after processing all exclusion sets. */
  1915. static pattern_set_el_t
  1916. process_presence_absence_patterns (char ***patterns, int num,
  1917. pos_t req_pos ATTRIBUTE_UNUSED,
  1918. int presence_p, int final_p)
  1919. {
  1920. pattern_set_el_t el_list;
  1921. pattern_set_el_t last_el;
  1922. pattern_set_el_t new_el;
  1923. decl_t decl_in_table;
  1924. int i, j;
  1925. el_list = NULL;
  1926. last_el = NULL;
  1927. for (i = 0; i < num; i++)
  1928. {
  1929. for (j = 0; patterns [i] [j] != NULL; j++)
  1930. ;
  1931. new_el = XCREATENODEVAR (struct pattern_set_el,
  1932. sizeof (struct pattern_set_el)
  1933. + sizeof (struct unit_decl *) * j);
  1934. new_el->unit_decls
  1935. = (struct unit_decl **) ((char *) new_el
  1936. + sizeof (struct pattern_set_el));
  1937. new_el->next_pattern_set_el = NULL;
  1938. if (last_el == NULL)
  1939. el_list = last_el = new_el;
  1940. else
  1941. {
  1942. last_el->next_pattern_set_el = new_el;
  1943. last_el = last_el->next_pattern_set_el;
  1944. }
  1945. new_el->units_num = 0;
  1946. for (j = 0; patterns [i] [j] != NULL; j++)
  1947. {
  1948. decl_in_table = find_decl (patterns [i] [j]);
  1949. if (decl_in_table == NULL)
  1950. error ((presence_p
  1951. ? (final_p
  1952. ? "unit `%s' in final presence set is not declared"
  1953. : "unit `%s' in presence set is not declared")
  1954. : (final_p
  1955. ? "unit `%s' in final absence set is not declared"
  1956. : "unit `%s' in absence set is not declared")),
  1957. patterns [i] [j]);
  1958. else if (decl_in_table->mode != dm_unit)
  1959. error ((presence_p
  1960. ? (final_p
  1961. ? "`%s' in final presence set is not unit"
  1962. : "`%s' in presence set is not unit")
  1963. : (final_p
  1964. ? "`%s' in final absence set is not unit"
  1965. : "`%s' in absence set is not unit")),
  1966. patterns [i] [j]);
  1967. else
  1968. {
  1969. new_el->unit_decls [new_el->units_num]
  1970. = DECL_UNIT (decl_in_table);
  1971. new_el->units_num++;
  1972. }
  1973. }
  1974. }
  1975. return el_list;
  1976. }
  1977. /* The function adds each element from PATTERN_LIST to presence (if
  1978. PRESENCE_P) or absence list of the each element from DEST_LIST.
  1979. Checking situations "unit requires own absence", and "unit excludes
  1980. and requires presence of ...", "unit requires absence and presence
  1981. of ...", "units in (final) presence set belong to different
  1982. automata", and "units in (final) absence set belong to different
  1983. automata". Remember that we process absence sets only after all
  1984. presence sets. */
  1985. static void
  1986. add_presence_absence (unit_set_el_t dest_list,
  1987. pattern_set_el_t pattern_list,
  1988. pos_t req_pos ATTRIBUTE_UNUSED,
  1989. int presence_p, int final_p)
  1990. {
  1991. unit_set_el_t dst;
  1992. pattern_set_el_t pat;
  1993. struct unit_decl *unit;
  1994. unit_set_el_t curr_excl_el;
  1995. pattern_set_el_t curr_pat_el;
  1996. pattern_set_el_t prev_el;
  1997. pattern_set_el_t copy;
  1998. int i;
  1999. int no_error_flag;
  2000. for (dst = dest_list; dst != NULL; dst = dst->next_unit_set_el)
  2001. for (pat = pattern_list; pat != NULL; pat = pat->next_pattern_set_el)
  2002. {
  2003. for (i = 0; i < pat->units_num; i++)
  2004. {
  2005. unit = pat->unit_decls [i];
  2006. if (dst->unit_decl == unit && pat->units_num == 1 && !presence_p)
  2007. {
  2008. error ("unit `%s' requires own absence", unit->name);
  2009. continue;
  2010. }
  2011. if (dst->unit_decl->automaton_name != NULL
  2012. && unit->automaton_name != NULL
  2013. && strcmp (dst->unit_decl->automaton_name,
  2014. unit->automaton_name) != 0)
  2015. {
  2016. error ((presence_p
  2017. ? (final_p
  2018. ? "units `%s' and `%s' in final presence set belong to different automata"
  2019. : "units `%s' and `%s' in presence set belong to different automata")
  2020. : (final_p
  2021. ? "units `%s' and `%s' in final absence set belong to different automata"
  2022. : "units `%s' and `%s' in absence set belong to different automata")),
  2023. unit->name, dst->unit_decl->name);
  2024. continue;
  2025. }
  2026. no_error_flag = 1;
  2027. if (presence_p)
  2028. for (curr_excl_el = dst->unit_decl->excl_list;
  2029. curr_excl_el != NULL;
  2030. curr_excl_el = curr_excl_el->next_unit_set_el)
  2031. {
  2032. if (unit == curr_excl_el->unit_decl && pat->units_num == 1)
  2033. {
  2034. if (!w_flag)
  2035. {
  2036. error ("unit `%s' excludes and requires presence of `%s'",
  2037. dst->unit_decl->name, unit->name);
  2038. no_error_flag = 0;
  2039. }
  2040. else
  2041. warning ("unit `%s' excludes and requires presence of `%s'",
  2042. dst->unit_decl->name, unit->name);
  2043. }
  2044. }
  2045. else if (pat->units_num == 1)
  2046. for (curr_pat_el = dst->unit_decl->presence_list;
  2047. curr_pat_el != NULL;
  2048. curr_pat_el = curr_pat_el->next_pattern_set_el)
  2049. if (curr_pat_el->units_num == 1
  2050. && unit == curr_pat_el->unit_decls [0])
  2051. {
  2052. if (!w_flag)
  2053. {
  2054. error ("unit `%s' requires absence and presence of `%s'",
  2055. dst->unit_decl->name, unit->name);
  2056. no_error_flag = 0;
  2057. }
  2058. else
  2059. warning ("unit `%s' requires absence and presence of `%s'",
  2060. dst->unit_decl->name, unit->name);
  2061. }
  2062. if (no_error_flag)
  2063. {
  2064. for (prev_el = (presence_p
  2065. ? (final_p
  2066. ? dst->unit_decl->final_presence_list
  2067. : dst->unit_decl->presence_list)
  2068. : (final_p
  2069. ? dst->unit_decl->final_absence_list
  2070. : dst->unit_decl->absence_list));
  2071. prev_el != NULL && prev_el->next_pattern_set_el != NULL;
  2072. prev_el = prev_el->next_pattern_set_el)
  2073. ;
  2074. copy = XCOPYNODE (struct pattern_set_el, pat);
  2075. copy->next_pattern_set_el = NULL;
  2076. if (prev_el == NULL)
  2077. {
  2078. if (presence_p)
  2079. {
  2080. if (final_p)
  2081. dst->unit_decl->final_presence_list = copy;
  2082. else
  2083. dst->unit_decl->presence_list = copy;
  2084. }
  2085. else if (final_p)
  2086. dst->unit_decl->final_absence_list = copy;
  2087. else
  2088. dst->unit_decl->absence_list = copy;
  2089. }
  2090. else
  2091. prev_el->next_pattern_set_el = copy;
  2092. }
  2093. }
  2094. }
  2095. }
  2096. /* The function inserts BYPASS in the list of bypasses of the
  2097. corresponding output insn. The order of bypasses in the list is
  2098. described in a comment for member `bypass_list' (see above). If
  2099. there is already the same bypass in the list the function reports
  2100. this and does nothing. */
  2101. static void
  2102. insert_bypass (struct bypass_decl *bypass)
  2103. {
  2104. struct bypass_decl *curr, *last;
  2105. struct insn_reserv_decl *out_insn_reserv = bypass->out_insn_reserv;
  2106. struct insn_reserv_decl *in_insn_reserv = bypass->in_insn_reserv;
  2107. for (curr = out_insn_reserv->bypass_list, last = NULL;
  2108. curr != NULL;
  2109. last = curr, curr = curr->next)
  2110. if (curr->in_insn_reserv == in_insn_reserv)
  2111. {
  2112. if ((bypass->bypass_guard_name != NULL
  2113. && curr->bypass_guard_name != NULL
  2114. && ! strcmp (bypass->bypass_guard_name, curr->bypass_guard_name))
  2115. || bypass->bypass_guard_name == curr->bypass_guard_name)
  2116. {
  2117. if (bypass->bypass_guard_name == NULL)
  2118. {
  2119. if (!w_flag)
  2120. error ("the same bypass `%s - %s' is already defined",
  2121. bypass->out_pattern, bypass->in_pattern);
  2122. else
  2123. warning ("the same bypass `%s - %s' is already defined",
  2124. bypass->out_pattern, bypass->in_pattern);
  2125. }
  2126. else if (!w_flag)
  2127. error ("the same bypass `%s - %s' (guard %s) is already defined",
  2128. bypass->out_pattern, bypass->in_pattern,
  2129. bypass->bypass_guard_name);
  2130. else
  2131. warning
  2132. ("the same bypass `%s - %s' (guard %s) is already defined",
  2133. bypass->out_pattern, bypass->in_pattern,
  2134. bypass->bypass_guard_name);
  2135. return;
  2136. }
  2137. if (curr->bypass_guard_name == NULL)
  2138. break;
  2139. if (curr->next == NULL || curr->next->in_insn_reserv != in_insn_reserv)
  2140. {
  2141. last = curr;
  2142. break;
  2143. }
  2144. }
  2145. if (last == NULL)
  2146. {
  2147. bypass->next = out_insn_reserv->bypass_list;
  2148. out_insn_reserv->bypass_list = bypass;
  2149. }
  2150. else
  2151. {
  2152. bypass->next = last->next;
  2153. last->next = bypass;
  2154. }
  2155. }
  2156. /* BYPASS is a define_bypass decl that includes glob pattern PATTERN.
  2157. Call FN (BYPASS, INSN, DATA) for each matching instruction INSN. */
  2158. static void
  2159. for_each_matching_insn (decl_t bypass, const char *pattern,
  2160. void (*fn) (decl_t, decl_t, void *), void *data)
  2161. {
  2162. decl_t insn_reserv;
  2163. bool matched_p;
  2164. int i;
  2165. matched_p = false;
  2166. if (strpbrk (pattern, "*?["))
  2167. for (i = 0; i < description->decls_num; i++)
  2168. {
  2169. insn_reserv = description->decls[i];
  2170. if (insn_reserv->mode == dm_insn_reserv
  2171. && fnmatch (pattern, DECL_INSN_RESERV (insn_reserv)->name, 0) == 0)
  2172. {
  2173. fn (bypass, insn_reserv, data);
  2174. matched_p = true;
  2175. }
  2176. }
  2177. else
  2178. {
  2179. insn_reserv = find_insn_decl (pattern);
  2180. if (insn_reserv)
  2181. {
  2182. fn (bypass, insn_reserv, data);
  2183. matched_p = true;
  2184. }
  2185. }
  2186. if (!matched_p)
  2187. error ("there is no insn reservation that matches `%s'", pattern);
  2188. }
  2189. /* A subroutine of process_bypass that is called for each pair
  2190. of matching instructions. OUT_INSN_RESERV is the output
  2191. instruction and DATA is the input instruction. */
  2192. static void
  2193. process_bypass_2 (decl_t model, decl_t out_insn_reserv, void *data)
  2194. {
  2195. struct bypass_decl *bypass;
  2196. decl_t in_insn_reserv;
  2197. in_insn_reserv = (decl_t) data;
  2198. if (strcmp (DECL_INSN_RESERV (in_insn_reserv)->name,
  2199. DECL_BYPASS (model)->in_pattern) == 0
  2200. && strcmp (DECL_INSN_RESERV (out_insn_reserv)->name,
  2201. DECL_BYPASS (model)->out_pattern) == 0)
  2202. bypass = DECL_BYPASS (model);
  2203. else
  2204. {
  2205. bypass = XCNEW (struct bypass_decl);
  2206. bypass->latency = DECL_BYPASS (model)->latency;
  2207. bypass->out_pattern = DECL_INSN_RESERV (out_insn_reserv)->name;
  2208. bypass->in_pattern = DECL_INSN_RESERV (in_insn_reserv)->name;
  2209. bypass->bypass_guard_name = DECL_BYPASS (model)->bypass_guard_name;
  2210. }
  2211. bypass->out_insn_reserv = DECL_INSN_RESERV (out_insn_reserv);
  2212. bypass->in_insn_reserv = DECL_INSN_RESERV (in_insn_reserv);
  2213. insert_bypass (bypass);
  2214. }
  2215. /* A subroutine of process_bypass that is called for each input
  2216. instruction IN_INSN_RESERV. */
  2217. static void
  2218. process_bypass_1 (decl_t bypass, decl_t in_insn_reserv,
  2219. void *data ATTRIBUTE_UNUSED)
  2220. {
  2221. for_each_matching_insn (bypass, DECL_BYPASS (bypass)->out_pattern,
  2222. process_bypass_2, in_insn_reserv);
  2223. }
  2224. /* Process define_bypass decl BYPASS, inserting a bypass for each specific
  2225. pair of insn reservations. */
  2226. static void
  2227. process_bypass (decl_t bypass)
  2228. {
  2229. for_each_matching_insn (bypass, DECL_BYPASS (bypass)->in_pattern,
  2230. process_bypass_1, NULL);
  2231. }
  2232. /* The function processes pipeline description declarations, checks
  2233. their correctness, and forms exclusion/presence/absence sets. */
  2234. static void
  2235. process_decls (void)
  2236. {
  2237. decl_t decl;
  2238. decl_t automaton_decl;
  2239. decl_t decl_in_table;
  2240. int automaton_presence;
  2241. int i;
  2242. /* Checking repeated automata declarations. */
  2243. automaton_presence = 0;
  2244. for (i = 0; i < description->decls_num; i++)
  2245. {
  2246. decl = description->decls [i];
  2247. if (decl->mode == dm_automaton)
  2248. {
  2249. automaton_presence = 1;
  2250. decl_in_table = insert_automaton_decl (decl);
  2251. if (decl_in_table != decl)
  2252. {
  2253. if (!w_flag)
  2254. error ("repeated declaration of automaton `%s'",
  2255. DECL_AUTOMATON (decl)->name);
  2256. else
  2257. warning ("repeated declaration of automaton `%s'",
  2258. DECL_AUTOMATON (decl)->name);
  2259. }
  2260. }
  2261. }
  2262. /* Checking undeclared automata, repeated declarations (except for
  2263. automata) and correctness of their attributes (insn latency times
  2264. etc.). */
  2265. for (i = 0; i < description->decls_num; i++)
  2266. {
  2267. decl = description->decls [i];
  2268. if (decl->mode == dm_insn_reserv)
  2269. {
  2270. if (DECL_INSN_RESERV (decl)->default_latency < 0)
  2271. error ("define_insn_reservation `%s' has negative latency time",
  2272. DECL_INSN_RESERV (decl)->name);
  2273. DECL_INSN_RESERV (decl)->insn_num = description->insns_num;
  2274. description->insns_num++;
  2275. decl_in_table = insert_insn_decl (decl);
  2276. if (decl_in_table != decl)
  2277. error ("`%s' is already used as insn reservation name",
  2278. DECL_INSN_RESERV (decl)->name);
  2279. }
  2280. else if (decl->mode == dm_bypass)
  2281. {
  2282. if (DECL_BYPASS (decl)->latency < 0)
  2283. error ("define_bypass `%s - %s' has negative latency time",
  2284. DECL_BYPASS (decl)->out_pattern,
  2285. DECL_BYPASS (decl)->in_pattern);
  2286. }
  2287. else if (decl->mode == dm_unit || decl->mode == dm_reserv)
  2288. {
  2289. if (decl->mode == dm_unit)
  2290. {
  2291. DECL_UNIT (decl)->automaton_decl = NULL;
  2292. if (DECL_UNIT (decl)->automaton_name != NULL)
  2293. {
  2294. automaton_decl
  2295. = find_automaton_decl (DECL_UNIT (decl)->automaton_name);
  2296. if (automaton_decl == NULL)
  2297. error ("automaton `%s' is not declared",
  2298. DECL_UNIT (decl)->automaton_name);
  2299. else
  2300. {
  2301. DECL_AUTOMATON (automaton_decl)->automaton_is_used = 1;
  2302. DECL_UNIT (decl)->automaton_decl
  2303. = DECL_AUTOMATON (automaton_decl);
  2304. }
  2305. }
  2306. else if (automaton_presence)
  2307. error ("define_unit `%s' without automaton when one defined",
  2308. DECL_UNIT (decl)->name);
  2309. DECL_UNIT (decl)->unit_num = description->units_num;
  2310. description->units_num++;
  2311. if (strcmp (DECL_UNIT (decl)->name, NOTHING_NAME) == 0)
  2312. {
  2313. error ("`%s' is declared as cpu unit", NOTHING_NAME);
  2314. continue;
  2315. }
  2316. decl_in_table = find_decl (DECL_UNIT (decl)->name);
  2317. }
  2318. else
  2319. {
  2320. if (strcmp (DECL_RESERV (decl)->name, NOTHING_NAME) == 0)
  2321. {
  2322. error ("`%s' is declared as cpu reservation", NOTHING_NAME);
  2323. continue;
  2324. }
  2325. decl_in_table = find_decl (DECL_RESERV (decl)->name);
  2326. }
  2327. if (decl_in_table == NULL)
  2328. decl_in_table = insert_decl (decl);
  2329. else
  2330. {
  2331. if (decl->mode == dm_unit)
  2332. error ("repeated declaration of unit `%s'",
  2333. DECL_UNIT (decl)->name);
  2334. else
  2335. error ("repeated declaration of reservation `%s'",
  2336. DECL_RESERV (decl)->name);
  2337. }
  2338. }
  2339. }
  2340. /* Check bypasses and form list of bypasses for each (output)
  2341. insn. */
  2342. for (i = 0; i < description->decls_num; i++)
  2343. {
  2344. decl = description->decls [i];
  2345. if (decl->mode == dm_bypass)
  2346. process_bypass (decl);
  2347. }
  2348. /* Check exclusion set declarations and form exclusion sets. */
  2349. for (i = 0; i < description->decls_num; i++)
  2350. {
  2351. decl = description->decls [i];
  2352. if (decl->mode == dm_excl)
  2353. {
  2354. unit_set_el_t unit_set_el_list;
  2355. unit_set_el_t unit_set_el_list_2;
  2356. unit_set_el_list
  2357. = process_excls (DECL_EXCL (decl)->names,
  2358. DECL_EXCL (decl)->first_list_length, decl->pos);
  2359. unit_set_el_list_2
  2360. = process_excls (&DECL_EXCL (decl)->names
  2361. [DECL_EXCL (decl)->first_list_length],
  2362. DECL_EXCL (decl)->all_names_num
  2363. - DECL_EXCL (decl)->first_list_length,
  2364. decl->pos);
  2365. add_excls (unit_set_el_list, unit_set_el_list_2, decl->pos);
  2366. add_excls (unit_set_el_list_2, unit_set_el_list, decl->pos);
  2367. }
  2368. }
  2369. /* Check presence set declarations and form presence sets. */
  2370. for (i = 0; i < description->decls_num; i++)
  2371. {
  2372. decl = description->decls [i];
  2373. if (decl->mode == dm_presence)
  2374. {
  2375. unit_set_el_t unit_set_el_list;
  2376. pattern_set_el_t pattern_set_el_list;
  2377. unit_set_el_list
  2378. = process_presence_absence_names
  2379. (DECL_PRESENCE (decl)->names, DECL_PRESENCE (decl)->names_num,
  2380. decl->pos, TRUE, DECL_PRESENCE (decl)->final_p);
  2381. pattern_set_el_list
  2382. = process_presence_absence_patterns
  2383. (DECL_PRESENCE (decl)->patterns,
  2384. DECL_PRESENCE (decl)->patterns_num,
  2385. decl->pos, TRUE, DECL_PRESENCE (decl)->final_p);
  2386. add_presence_absence (unit_set_el_list, pattern_set_el_list,
  2387. decl->pos, TRUE,
  2388. DECL_PRESENCE (decl)->final_p);
  2389. }
  2390. }
  2391. /* Check absence set declarations and form absence sets. */
  2392. for (i = 0; i < description->decls_num; i++)
  2393. {
  2394. decl = description->decls [i];
  2395. if (decl->mode == dm_absence)
  2396. {
  2397. unit_set_el_t unit_set_el_list;
  2398. pattern_set_el_t pattern_set_el_list;
  2399. unit_set_el_list
  2400. = process_presence_absence_names
  2401. (DECL_ABSENCE (decl)->names, DECL_ABSENCE (decl)->names_num,
  2402. decl->pos, FALSE, DECL_ABSENCE (decl)->final_p);
  2403. pattern_set_el_list
  2404. = process_presence_absence_patterns
  2405. (DECL_ABSENCE (decl)->patterns,
  2406. DECL_ABSENCE (decl)->patterns_num,
  2407. decl->pos, FALSE, DECL_ABSENCE (decl)->final_p);
  2408. add_presence_absence (unit_set_el_list, pattern_set_el_list,
  2409. decl->pos, FALSE,
  2410. DECL_ABSENCE (decl)->final_p);
  2411. }
  2412. }
  2413. }
  2414. /* The following function checks that declared automaton is used. If
  2415. the automaton is not used, the function fixes error/warning. The
  2416. following function must be called only after `process_decls'. */
  2417. static void
  2418. check_automaton_usage (void)
  2419. {
  2420. decl_t decl;
  2421. int i;
  2422. for (i = 0; i < description->decls_num; i++)
  2423. {
  2424. decl = description->decls [i];
  2425. if (decl->mode == dm_automaton
  2426. && !DECL_AUTOMATON (decl)->automaton_is_used)
  2427. {
  2428. if (!w_flag)
  2429. error ("automaton `%s' is not used", DECL_AUTOMATON (decl)->name);
  2430. else
  2431. warning ("automaton `%s' is not used",
  2432. DECL_AUTOMATON (decl)->name);
  2433. }
  2434. }
  2435. }
  2436. /* The following recursive function processes all regexp in order to
  2437. fix usage of units or reservations and to fix errors of undeclared
  2438. name. The function may change unit_regexp onto reserv_regexp.
  2439. Remember that reserv_regexp does not exist before the function
  2440. call. */
  2441. static regexp_t
  2442. process_regexp (regexp_t regexp)
  2443. {
  2444. decl_t decl_in_table;
  2445. regexp_t new_regexp;
  2446. int i;
  2447. switch (regexp->mode)
  2448. {
  2449. case rm_unit:
  2450. decl_in_table = find_decl (REGEXP_UNIT (regexp)->name);
  2451. if (decl_in_table == NULL)
  2452. error ("undeclared unit or reservation `%s'",
  2453. REGEXP_UNIT (regexp)->name);
  2454. else
  2455. switch (decl_in_table->mode)
  2456. {
  2457. case dm_unit:
  2458. DECL_UNIT (decl_in_table)->unit_is_used = 1;
  2459. REGEXP_UNIT (regexp)->unit_decl = DECL_UNIT (decl_in_table);
  2460. break;
  2461. case dm_reserv:
  2462. DECL_RESERV (decl_in_table)->reserv_is_used = 1;
  2463. new_regexp = XCREATENODE (struct regexp);
  2464. new_regexp->mode = rm_reserv;
  2465. new_regexp->pos = regexp->pos;
  2466. REGEXP_RESERV (new_regexp)->name = REGEXP_UNIT (regexp)->name;
  2467. REGEXP_RESERV (new_regexp)->reserv_decl
  2468. = DECL_RESERV (decl_in_table);
  2469. regexp = new_regexp;
  2470. break;
  2471. default:
  2472. gcc_unreachable ();
  2473. }
  2474. break;
  2475. case rm_sequence:
  2476. for (i = 0; i <REGEXP_SEQUENCE (regexp)->regexps_num; i++)
  2477. REGEXP_SEQUENCE (regexp)->regexps [i]
  2478. = process_regexp (REGEXP_SEQUENCE (regexp)->regexps [i]);
  2479. break;
  2480. case rm_allof:
  2481. for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
  2482. REGEXP_ALLOF (regexp)->regexps [i]
  2483. = process_regexp (REGEXP_ALLOF (regexp)->regexps [i]);
  2484. break;
  2485. case rm_oneof:
  2486. for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
  2487. REGEXP_ONEOF (regexp)->regexps [i]
  2488. = process_regexp (REGEXP_ONEOF (regexp)->regexps [i]);
  2489. break;
  2490. case rm_repeat:
  2491. REGEXP_REPEAT (regexp)->regexp
  2492. = process_regexp (REGEXP_REPEAT (regexp)->regexp);
  2493. break;
  2494. case rm_nothing:
  2495. break;
  2496. default:
  2497. gcc_unreachable ();
  2498. }
  2499. return regexp;
  2500. }
  2501. /* The following function processes regexp of define_reservation and
  2502. define_insn_reservation with the aid of function
  2503. `process_regexp'. */
  2504. static void
  2505. process_regexp_decls (void)
  2506. {
  2507. decl_t decl;
  2508. int i;
  2509. for (i = 0; i < description->decls_num; i++)
  2510. {
  2511. decl = description->decls [i];
  2512. if (decl->mode == dm_reserv)
  2513. DECL_RESERV (decl)->regexp
  2514. = process_regexp (DECL_RESERV (decl)->regexp);
  2515. else if (decl->mode == dm_insn_reserv)
  2516. DECL_INSN_RESERV (decl)->regexp
  2517. = process_regexp (DECL_INSN_RESERV (decl)->regexp);
  2518. }
  2519. }
  2520. /* The following function checks that declared unit is used. If the
  2521. unit is not used, the function fixes errors/warnings. The
  2522. following function must be called only after `process_decls',
  2523. `process_regexp_decls'. */
  2524. static void
  2525. check_usage (void)
  2526. {
  2527. decl_t decl;
  2528. int i;
  2529. for (i = 0; i < description->decls_num; i++)
  2530. {
  2531. decl = description->decls [i];
  2532. if (decl->mode == dm_unit && !DECL_UNIT (decl)->unit_is_used)
  2533. {
  2534. if (!w_flag)
  2535. error ("unit `%s' is not used", DECL_UNIT (decl)->name);
  2536. else
  2537. warning ("unit `%s' is not used", DECL_UNIT (decl)->name);
  2538. }
  2539. else if (decl->mode == dm_reserv && !DECL_RESERV (decl)->reserv_is_used)
  2540. {
  2541. if (!w_flag)
  2542. error ("reservation `%s' is not used", DECL_RESERV (decl)->name);
  2543. else
  2544. warning ("reservation `%s' is not used", DECL_RESERV (decl)->name);
  2545. }
  2546. }
  2547. }
  2548. /* The following variable value is number of reservation being
  2549. processed on loop recognition. */
  2550. static int curr_loop_pass_num;
  2551. /* The following recursive function returns nonzero value if REGEXP
  2552. contains given decl or reservations in given regexp refers for
  2553. given decl. */
  2554. static int
  2555. loop_in_regexp (regexp_t regexp, decl_t start_decl)
  2556. {
  2557. int i;
  2558. if (regexp == NULL)
  2559. return 0;
  2560. switch (regexp->mode)
  2561. {
  2562. case rm_unit:
  2563. return 0;
  2564. case rm_reserv:
  2565. if (start_decl->mode == dm_reserv
  2566. && REGEXP_RESERV (regexp)->reserv_decl == DECL_RESERV (start_decl))
  2567. return 1;
  2568. else if (REGEXP_RESERV (regexp)->reserv_decl->loop_pass_num
  2569. == curr_loop_pass_num)
  2570. /* declaration has been processed. */
  2571. return 0;
  2572. else
  2573. {
  2574. REGEXP_RESERV (regexp)->reserv_decl->loop_pass_num
  2575. = curr_loop_pass_num;
  2576. return loop_in_regexp (REGEXP_RESERV (regexp)->reserv_decl->regexp,
  2577. start_decl);
  2578. }
  2579. case rm_sequence:
  2580. for (i = 0; i <REGEXP_SEQUENCE (regexp)->regexps_num; i++)
  2581. if (loop_in_regexp (REGEXP_SEQUENCE (regexp)->regexps [i], start_decl))
  2582. return 1;
  2583. return 0;
  2584. case rm_allof:
  2585. for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
  2586. if (loop_in_regexp (REGEXP_ALLOF (regexp)->regexps [i], start_decl))
  2587. return 1;
  2588. return 0;
  2589. case rm_oneof:
  2590. for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
  2591. if (loop_in_regexp (REGEXP_ONEOF (regexp)->regexps [i], start_decl))
  2592. return 1;
  2593. return 0;
  2594. case rm_repeat:
  2595. return loop_in_regexp (REGEXP_REPEAT (regexp)->regexp, start_decl);
  2596. case rm_nothing:
  2597. return 0;
  2598. default:
  2599. gcc_unreachable ();
  2600. }
  2601. }
  2602. /* The following function fixes errors "cycle in definition ...". The
  2603. function uses function `loop_in_regexp' for that. */
  2604. static void
  2605. check_loops_in_regexps (void)
  2606. {
  2607. decl_t decl;
  2608. int i;
  2609. for (i = 0; i < description->decls_num; i++)
  2610. {
  2611. decl = description->decls [i];
  2612. if (decl->mode == dm_reserv)
  2613. DECL_RESERV (decl)->loop_pass_num = 0;
  2614. }
  2615. for (i = 0; i < description->decls_num; i++)
  2616. {
  2617. decl = description->decls [i];
  2618. curr_loop_pass_num = i;
  2619. if (decl->mode == dm_reserv)
  2620. {
  2621. DECL_RESERV (decl)->loop_pass_num = curr_loop_pass_num;
  2622. if (loop_in_regexp (DECL_RESERV (decl)->regexp, decl))
  2623. {
  2624. gcc_assert (DECL_RESERV (decl)->regexp);
  2625. error ("cycle in definition of reservation `%s'",
  2626. DECL_RESERV (decl)->name);
  2627. }
  2628. }
  2629. }
  2630. }
  2631. /* The function recursively processes IR of reservation and defines
  2632. max and min cycle for reservation of unit. */
  2633. static void
  2634. process_regexp_cycles (regexp_t regexp, int max_start_cycle,
  2635. int min_start_cycle, int *max_finish_cycle,
  2636. int *min_finish_cycle)
  2637. {
  2638. int i;
  2639. switch (regexp->mode)
  2640. {
  2641. case rm_unit:
  2642. if (REGEXP_UNIT (regexp)->unit_decl->max_occ_cycle_num < max_start_cycle)
  2643. REGEXP_UNIT (regexp)->unit_decl->max_occ_cycle_num = max_start_cycle;
  2644. if (REGEXP_UNIT (regexp)->unit_decl->min_occ_cycle_num > min_start_cycle
  2645. || REGEXP_UNIT (regexp)->unit_decl->min_occ_cycle_num == -1)
  2646. REGEXP_UNIT (regexp)->unit_decl->min_occ_cycle_num = min_start_cycle;
  2647. *max_finish_cycle = max_start_cycle;
  2648. *min_finish_cycle = min_start_cycle;
  2649. break;
  2650. case rm_reserv:
  2651. process_regexp_cycles (REGEXP_RESERV (regexp)->reserv_decl->regexp,
  2652. max_start_cycle, min_start_cycle,
  2653. max_finish_cycle, min_finish_cycle);
  2654. break;
  2655. case rm_repeat:
  2656. for (i = 0; i < REGEXP_REPEAT (regexp)->repeat_num; i++)
  2657. {
  2658. process_regexp_cycles (REGEXP_REPEAT (regexp)->regexp,
  2659. max_start_cycle, min_start_cycle,
  2660. max_finish_cycle, min_finish_cycle);
  2661. max_start_cycle = *max_finish_cycle + 1;
  2662. min_start_cycle = *min_finish_cycle + 1;
  2663. }
  2664. break;
  2665. case rm_sequence:
  2666. for (i = 0; i <REGEXP_SEQUENCE (regexp)->regexps_num; i++)
  2667. {
  2668. process_regexp_cycles (REGEXP_SEQUENCE (regexp)->regexps [i],
  2669. max_start_cycle, min_start_cycle,
  2670. max_finish_cycle, min_finish_cycle);
  2671. max_start_cycle = *max_finish_cycle + 1;
  2672. min_start_cycle = *min_finish_cycle + 1;
  2673. }
  2674. break;
  2675. case rm_allof:
  2676. {
  2677. int max_cycle = 0;
  2678. int min_cycle = 0;
  2679. for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
  2680. {
  2681. process_regexp_cycles (REGEXP_ALLOF (regexp)->regexps [i],
  2682. max_start_cycle, min_start_cycle,
  2683. max_finish_cycle, min_finish_cycle);
  2684. if (max_cycle < *max_finish_cycle)
  2685. max_cycle = *max_finish_cycle;
  2686. if (i == 0 || min_cycle > *min_finish_cycle)
  2687. min_cycle = *min_finish_cycle;
  2688. }
  2689. *max_finish_cycle = max_cycle;
  2690. *min_finish_cycle = min_cycle;
  2691. }
  2692. break;
  2693. case rm_oneof:
  2694. {
  2695. int max_cycle = 0;
  2696. int min_cycle = 0;
  2697. for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
  2698. {
  2699. process_regexp_cycles (REGEXP_ONEOF (regexp)->regexps [i],
  2700. max_start_cycle, min_start_cycle,
  2701. max_finish_cycle, min_finish_cycle);
  2702. if (max_cycle < *max_finish_cycle)
  2703. max_cycle = *max_finish_cycle;
  2704. if (i == 0 || min_cycle > *min_finish_cycle)
  2705. min_cycle = *min_finish_cycle;
  2706. }
  2707. *max_finish_cycle = max_cycle;
  2708. *min_finish_cycle = min_cycle;
  2709. }
  2710. break;
  2711. case rm_nothing:
  2712. *max_finish_cycle = max_start_cycle;
  2713. *min_finish_cycle = min_start_cycle;
  2714. break;
  2715. default:
  2716. gcc_unreachable ();
  2717. }
  2718. }
  2719. /* The following function is called only for correct program. The
  2720. function defines max reservation of insns in cycles. */
  2721. static void
  2722. evaluate_max_reserv_cycles (void)
  2723. {
  2724. int max_insn_cycles_num;
  2725. int min_insn_cycles_num;
  2726. decl_t decl;
  2727. int i;
  2728. description->max_insn_reserv_cycles = 0;
  2729. for (i = 0; i < description->decls_num; i++)
  2730. {
  2731. decl = description->decls [i];
  2732. if (decl->mode == dm_insn_reserv)
  2733. {
  2734. process_regexp_cycles (DECL_INSN_RESERV (decl)->regexp, 0, 0,
  2735. &max_insn_cycles_num, &min_insn_cycles_num);
  2736. if (description->max_insn_reserv_cycles < max_insn_cycles_num)
  2737. description->max_insn_reserv_cycles = max_insn_cycles_num;
  2738. }
  2739. }
  2740. description->max_insn_reserv_cycles++;
  2741. }
  2742. /* The following function calls functions for checking all
  2743. description. */
  2744. static void
  2745. check_all_description (void)
  2746. {
  2747. process_decls ();
  2748. check_automaton_usage ();
  2749. process_regexp_decls ();
  2750. check_usage ();
  2751. check_loops_in_regexps ();
  2752. if (!have_error)
  2753. evaluate_max_reserv_cycles ();
  2754. }
  2755. /* The page contains abstract data `ticker'. This data is used to
  2756. report time of different phases of building automata. It is
  2757. possibly to write a description for which automata will be built
  2758. during several minutes even on fast machine. */
  2759. /* The following function creates ticker and makes it active. */
  2760. static ticker_t
  2761. create_ticker (void)
  2762. {
  2763. ticker_t ticker;
  2764. ticker.modified_creation_time = get_run_time ();
  2765. ticker.incremented_off_time = 0;
  2766. return ticker;
  2767. }
  2768. /* The following function switches off given ticker. */
  2769. static void
  2770. ticker_off (ticker_t *ticker)
  2771. {
  2772. if (ticker->incremented_off_time == 0)
  2773. ticker->incremented_off_time = get_run_time () + 1;
  2774. }
  2775. /* The following function switches on given ticker. */
  2776. static void
  2777. ticker_on (ticker_t *ticker)
  2778. {
  2779. if (ticker->incremented_off_time != 0)
  2780. {
  2781. ticker->modified_creation_time
  2782. += get_run_time () - ticker->incremented_off_time + 1;
  2783. ticker->incremented_off_time = 0;
  2784. }
  2785. }
  2786. /* The following function returns current time in milliseconds since
  2787. the moment when given ticker was created. */
  2788. static int
  2789. active_time (ticker_t ticker)
  2790. {
  2791. if (ticker.incremented_off_time != 0)
  2792. return ticker.incremented_off_time - 1 - ticker.modified_creation_time;
  2793. else
  2794. return get_run_time () - ticker.modified_creation_time;
  2795. }
  2796. /* The following function returns string representation of active time
  2797. of given ticker. The result is string representation of seconds
  2798. with accuracy of 1/100 second. Only result of the last call of the
  2799. function exists. Therefore the following code is not correct
  2800. printf ("parser time: %s\ngeneration time: %s\n",
  2801. active_time_string (parser_ticker),
  2802. active_time_string (generation_ticker));
  2803. Correct code has to be the following
  2804. printf ("parser time: %s\n", active_time_string (parser_ticker));
  2805. printf ("generation time: %s\n",
  2806. active_time_string (generation_ticker));
  2807. */
  2808. static void
  2809. print_active_time (FILE *f, ticker_t ticker)
  2810. {
  2811. int msecs;
  2812. msecs = active_time (ticker);
  2813. fprintf (f, "%d.%06d", msecs / 1000000, msecs % 1000000);
  2814. }
  2815. /* The following variable value is number of automaton which are
  2816. really being created. This value is defined on the base of
  2817. argument of option `-split'. If the variable has zero value the
  2818. number of automata is defined by the constructions `%automaton'.
  2819. This case occurs when option `-split' is absent or has zero
  2820. argument. If constructions `define_automaton' is absent only one
  2821. automaton is created. */
  2822. static int automata_num;
  2823. /* The following variable values are times of
  2824. o transformation of regular expressions
  2825. o building NDFA (DFA if !ndfa_flag)
  2826. o NDFA -> DFA (simply the same automaton if !ndfa_flag)
  2827. o DFA minimization
  2828. o building insn equivalence classes
  2829. o all previous ones
  2830. o code output */
  2831. static ticker_t transform_time;
  2832. static ticker_t NDFA_time;
  2833. static ticker_t NDFA_to_DFA_time;
  2834. static ticker_t minimize_time;
  2835. static ticker_t equiv_time;
  2836. static ticker_t automaton_generation_time;
  2837. static ticker_t output_time;
  2838. /* The following variable values are times of
  2839. all checking
  2840. all generation
  2841. all pipeline hazard translator work */
  2842. static ticker_t check_time;
  2843. static ticker_t generation_time;
  2844. static ticker_t all_time;
  2845. /* Pseudo insn decl which denotes advancing cycle. */
  2846. static decl_t advance_cycle_insn_decl;
  2847. /* Pseudo insn decl which denotes collapsing the NDFA state. */
  2848. static decl_t collapse_ndfa_insn_decl;
  2849. /* Create and record a decl for the special advance-cycle transition. */
  2850. static void
  2851. add_advance_cycle_insn_decl (void)
  2852. {
  2853. advance_cycle_insn_decl = XCREATENODE (struct decl);
  2854. advance_cycle_insn_decl->mode = dm_insn_reserv;
  2855. advance_cycle_insn_decl->pos = no_pos;
  2856. DECL_INSN_RESERV (advance_cycle_insn_decl)->regexp = NULL;
  2857. DECL_INSN_RESERV (advance_cycle_insn_decl)->name = "$advance_cycle";
  2858. DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num
  2859. = description->insns_num;
  2860. description->decls [description->decls_num] = advance_cycle_insn_decl;
  2861. description->decls_num++;
  2862. description->insns_num++;
  2863. }
  2864. /* Create and record a decl for the special collapse-NDFA transition. */
  2865. static void
  2866. add_collapse_ndfa_insn_decl (void)
  2867. {
  2868. collapse_ndfa_insn_decl = XCREATENODE (struct decl);
  2869. collapse_ndfa_insn_decl->mode = dm_insn_reserv;
  2870. collapse_ndfa_insn_decl->pos = no_pos;
  2871. DECL_INSN_RESERV (collapse_ndfa_insn_decl)->regexp = NULL;
  2872. DECL_INSN_RESERV (collapse_ndfa_insn_decl)->name = "$collapse_ndfa";
  2873. DECL_INSN_RESERV (collapse_ndfa_insn_decl)->insn_num
  2874. = description->insns_num;
  2875. description->decls [description->decls_num] = collapse_ndfa_insn_decl;
  2876. description->decls_num++;
  2877. description->insns_num++;
  2878. }
  2879. /* True if DECL is either of the two special decls we created. */
  2880. static bool
  2881. special_decl_p (struct insn_reserv_decl *decl)
  2882. {
  2883. return (decl == DECL_INSN_RESERV (advance_cycle_insn_decl)
  2884. || (collapse_flag
  2885. && decl == DECL_INSN_RESERV (collapse_ndfa_insn_decl)));
  2886. }
  2887. /* Abstract data `alternative states' which represents
  2888. nondeterministic nature of the description (see comments for
  2889. structures alt_state and state). */
  2890. /* List of free states. */
  2891. static alt_state_t first_free_alt_state;
  2892. #ifndef NDEBUG
  2893. /* The following variables is maximal number of allocated nodes
  2894. alt_state. */
  2895. static int allocated_alt_states_num = 0;
  2896. #endif
  2897. /* The following function returns free node alt_state. It may be new
  2898. allocated node or node freed earlier. */
  2899. static alt_state_t
  2900. get_free_alt_state (void)
  2901. {
  2902. alt_state_t result;
  2903. if (first_free_alt_state != NULL)
  2904. {
  2905. result = first_free_alt_state;
  2906. first_free_alt_state = first_free_alt_state->next_alt_state;
  2907. }
  2908. else
  2909. {
  2910. #ifndef NDEBUG
  2911. allocated_alt_states_num++;
  2912. #endif
  2913. result = XCREATENODE (struct alt_state);
  2914. }
  2915. result->state = NULL;
  2916. result->next_alt_state = NULL;
  2917. result->next_sorted_alt_state = NULL;
  2918. return result;
  2919. }
  2920. /* The function frees node ALT_STATE. */
  2921. static void
  2922. free_alt_state (alt_state_t alt_state)
  2923. {
  2924. if (alt_state == NULL)
  2925. return;
  2926. alt_state->next_alt_state = first_free_alt_state;
  2927. first_free_alt_state = alt_state;
  2928. }
  2929. /* The function frees list started with node ALT_STATE_LIST. */
  2930. static void
  2931. free_alt_states (alt_state_t alt_states_list)
  2932. {
  2933. alt_state_t curr_alt_state;
  2934. alt_state_t next_alt_state;
  2935. for (curr_alt_state = alt_states_list;
  2936. curr_alt_state != NULL;
  2937. curr_alt_state = next_alt_state)
  2938. {
  2939. next_alt_state = curr_alt_state->next_alt_state;
  2940. free_alt_state (curr_alt_state);
  2941. }
  2942. }
  2943. /* The function compares unique numbers of alt states. */
  2944. static int
  2945. alt_state_cmp (const void *alt_state_ptr_1, const void *alt_state_ptr_2)
  2946. {
  2947. if ((*(const alt_state_t *) alt_state_ptr_1)->state->unique_num
  2948. == (*(const alt_state_t *) alt_state_ptr_2)->state->unique_num)
  2949. return 0;
  2950. else if ((*(const alt_state_t *) alt_state_ptr_1)->state->unique_num
  2951. < (*(const alt_state_t *) alt_state_ptr_2)->state->unique_num)
  2952. return -1;
  2953. else
  2954. return 1;
  2955. }
  2956. /* The function sorts ALT_STATES_LIST and removes duplicated alt
  2957. states from the list. The comparison key is alt state unique
  2958. number. */
  2959. static alt_state_t
  2960. uniq_sort_alt_states (alt_state_t alt_states_list)
  2961. {
  2962. alt_state_t curr_alt_state;
  2963. size_t i;
  2964. size_t prev_unique_state_ind;
  2965. alt_state_t result;
  2966. if (alt_states_list == 0)
  2967. return 0;
  2968. if (alt_states_list->next_alt_state == 0)
  2969. return alt_states_list;
  2970. auto_vec<alt_state_t, 150> alt_states;
  2971. for (curr_alt_state = alt_states_list;
  2972. curr_alt_state != NULL;
  2973. curr_alt_state = curr_alt_state->next_alt_state)
  2974. alt_states.safe_push (curr_alt_state);
  2975. alt_states.qsort (alt_state_cmp);
  2976. prev_unique_state_ind = 0;
  2977. for (i = 1; i < alt_states.length (); i++)
  2978. if (alt_states[prev_unique_state_ind]->state != alt_states[i]->state)
  2979. {
  2980. prev_unique_state_ind++;
  2981. alt_states[prev_unique_state_ind] = alt_states[i];
  2982. }
  2983. alt_states.truncate (prev_unique_state_ind + 1);
  2984. for (i = 1; i < alt_states.length (); i++)
  2985. alt_states[i-1]->next_sorted_alt_state
  2986. = alt_states[i];
  2987. alt_states.last ()->next_sorted_alt_state = 0;
  2988. result = alt_states[0];
  2989. return result;
  2990. }
  2991. /* The function checks equality of alt state lists. Remember that the
  2992. lists must be already sorted by the previous function. */
  2993. static int
  2994. alt_states_eq (alt_state_t alt_states_1, alt_state_t alt_states_2)
  2995. {
  2996. while (alt_states_1 != NULL && alt_states_2 != NULL
  2997. && alt_state_cmp (&alt_states_1, &alt_states_2) == 0)
  2998. {
  2999. alt_states_1 = alt_states_1->next_sorted_alt_state;
  3000. alt_states_2 = alt_states_2->next_sorted_alt_state;
  3001. }
  3002. return alt_states_1 == alt_states_2;
  3003. }
  3004. /* Initialization of the abstract data. */
  3005. static void
  3006. initiate_alt_states (void)
  3007. {
  3008. first_free_alt_state = NULL;
  3009. }
  3010. /* Finishing work with the abstract data. */
  3011. static void
  3012. finish_alt_states (void)
  3013. {
  3014. }
  3015. /* The page contains macros for work with bits strings. We could use
  3016. standard gcc bitmap or sbitmap but it would result in difficulties
  3017. of building canadian cross. */
  3018. /* Set bit number bitno in the bit string. The macro is not side
  3019. effect proof. */
  3020. #define bitmap_set_bit(bitstring, bitno) \
  3021. ((bitstring)[(bitno) / (sizeof (*(bitstring)) * CHAR_BIT)] |= \
  3022. (HOST_WIDE_INT)1 << (bitno) % (sizeof (*(bitstring)) * CHAR_BIT))
  3023. #define CLEAR_BIT(bitstring, bitno) \
  3024. ((bitstring)[(bitno) / (sizeof (*(bitstring)) * CHAR_BIT)] &= \
  3025. ~((HOST_WIDE_INT)1 << (bitno) % (sizeof (*(bitstring)) * CHAR_BIT)))
  3026. /* Test if bit number bitno in the bitstring is set. The macro is not
  3027. side effect proof. */
  3028. #define bitmap_bit_p(bitstring, bitno) \
  3029. ((bitstring)[(bitno) / (sizeof (*(bitstring)) * CHAR_BIT)] >> \
  3030. (bitno) % (sizeof (*(bitstring)) * CHAR_BIT) & 1)
  3031. /* This page contains abstract data `state'. */
  3032. /* Maximal length of reservations in cycles (>= 1). */
  3033. static int max_cycles_num;
  3034. /* Number of set elements (see type set_el_t) needed for
  3035. representation of one cycle reservation. It is depended on units
  3036. number. */
  3037. static int els_in_cycle_reserv;
  3038. /* Number of set elements (see type set_el_t) needed for
  3039. representation of maximal length reservation. Deterministic
  3040. reservation is stored as set (bit string) of length equal to the
  3041. variable value * number of bits in set_el_t. */
  3042. static int els_in_reservs;
  3043. /* Array of pointers to unit declarations. */
  3044. static unit_decl_t *units_array;
  3045. /* Temporary reservation of maximal length. */
  3046. static reserv_sets_t temp_reserv;
  3047. /* The state table itself is represented by the following variable. */
  3048. static htab_t state_table;
  3049. /* Linked list of free 'state' structures to be recycled. The
  3050. next_equiv_class_state pointer is borrowed for a free list. */
  3051. static state_t first_free_state;
  3052. static int curr_unique_state_num;
  3053. #ifndef NDEBUG
  3054. /* The following variables is maximal number of allocated nodes
  3055. `state'. */
  3056. static int allocated_states_num = 0;
  3057. #endif
  3058. /* Allocate new reservation set. */
  3059. static reserv_sets_t
  3060. alloc_empty_reserv_sets (void)
  3061. {
  3062. reserv_sets_t result;
  3063. obstack_blank (&irp, els_in_reservs * sizeof (set_el_t));
  3064. result = (reserv_sets_t) obstack_base (&irp);
  3065. obstack_finish (&irp);
  3066. memset (result, 0, els_in_reservs * sizeof (set_el_t));
  3067. return result;
  3068. }
  3069. /* Hash value of reservation set. */
  3070. static unsigned
  3071. reserv_sets_hash_value (reserv_sets_t reservs)
  3072. {
  3073. set_el_t hash_value;
  3074. unsigned result;
  3075. int reservs_num, i;
  3076. set_el_t *reserv_ptr;
  3077. hash_value = 0;
  3078. reservs_num = els_in_reservs;
  3079. reserv_ptr = reservs;
  3080. i = 0;
  3081. while (reservs_num != 0)
  3082. {
  3083. reservs_num--;
  3084. hash_value += ((*reserv_ptr >> i)
  3085. | (*reserv_ptr << (((sizeof (set_el_t) * CHAR_BIT) - 1) & -i)));
  3086. i++;
  3087. if (i == sizeof (set_el_t) * CHAR_BIT)
  3088. i = 0;
  3089. reserv_ptr++;
  3090. }
  3091. if (sizeof (set_el_t) <= sizeof (unsigned))
  3092. return hash_value;
  3093. result = 0;
  3094. for (i = sizeof (set_el_t); i > 0; i -= sizeof (unsigned) - 1)
  3095. {
  3096. result += (unsigned) hash_value;
  3097. hash_value >>= (sizeof (unsigned) - 1) * CHAR_BIT;
  3098. }
  3099. return result;
  3100. }
  3101. /* Comparison of given reservation sets. */
  3102. static int
  3103. reserv_sets_cmp (const_reserv_sets_t reservs_1, const_reserv_sets_t reservs_2)
  3104. {
  3105. int reservs_num;
  3106. const set_el_t *reserv_ptr_1;
  3107. const set_el_t *reserv_ptr_2;
  3108. gcc_assert (reservs_1 && reservs_2);
  3109. reservs_num = els_in_reservs;
  3110. reserv_ptr_1 = reservs_1;
  3111. reserv_ptr_2 = reservs_2;
  3112. while (reservs_num != 0 && *reserv_ptr_1 == *reserv_ptr_2)
  3113. {
  3114. reservs_num--;
  3115. reserv_ptr_1++;
  3116. reserv_ptr_2++;
  3117. }
  3118. if (reservs_num == 0)
  3119. return 0;
  3120. else if (*reserv_ptr_1 < *reserv_ptr_2)
  3121. return -1;
  3122. else
  3123. return 1;
  3124. }
  3125. /* The function checks equality of the reservation sets. */
  3126. static int
  3127. reserv_sets_eq (const_reserv_sets_t reservs_1, const_reserv_sets_t reservs_2)
  3128. {
  3129. return reserv_sets_cmp (reservs_1, reservs_2) == 0;
  3130. }
  3131. /* Set up in the reservation set that unit with UNIT_NUM is used on
  3132. CYCLE_NUM. */
  3133. static void
  3134. set_unit_reserv (reserv_sets_t reservs, int cycle_num, int unit_num)
  3135. {
  3136. gcc_assert (cycle_num < max_cycles_num);
  3137. bitmap_set_bit (reservs, cycle_num * els_in_cycle_reserv
  3138. * sizeof (set_el_t) * CHAR_BIT + unit_num);
  3139. }
  3140. /* Set up in the reservation set RESERVS that unit with UNIT_NUM is
  3141. used on CYCLE_NUM. */
  3142. static int
  3143. test_unit_reserv (reserv_sets_t reservs, int cycle_num, int unit_num)
  3144. {
  3145. gcc_assert (cycle_num < max_cycles_num);
  3146. return bitmap_bit_p (reservs, cycle_num * els_in_cycle_reserv
  3147. * sizeof (set_el_t) * CHAR_BIT + unit_num);
  3148. }
  3149. /* The function checks that the reservation sets are intersected,
  3150. i.e. there is a unit reservation on a cycle in both reservation
  3151. sets. */
  3152. static int
  3153. reserv_sets_are_intersected (reserv_sets_t operand_1,
  3154. reserv_sets_t operand_2)
  3155. {
  3156. set_el_t *el_ptr_1;
  3157. set_el_t *el_ptr_2;
  3158. set_el_t *cycle_ptr_1;
  3159. set_el_t *cycle_ptr_2;
  3160. gcc_assert (operand_1 && operand_2);
  3161. for (el_ptr_1 = operand_1, el_ptr_2 = operand_2;
  3162. el_ptr_1 < operand_1 + els_in_reservs;
  3163. el_ptr_1++, el_ptr_2++)
  3164. if (*el_ptr_1 & *el_ptr_2)
  3165. return 1;
  3166. reserv_sets_or (temp_reserv, operand_1, operand_2);
  3167. for (cycle_ptr_1 = operand_1, cycle_ptr_2 = operand_2;
  3168. cycle_ptr_1 < operand_1 + els_in_reservs;
  3169. cycle_ptr_1 += els_in_cycle_reserv, cycle_ptr_2 += els_in_cycle_reserv)
  3170. {
  3171. for (el_ptr_1 = cycle_ptr_1, el_ptr_2 = get_excl_set (cycle_ptr_2);
  3172. el_ptr_1 < cycle_ptr_1 + els_in_cycle_reserv;
  3173. el_ptr_1++, el_ptr_2++)
  3174. if (*el_ptr_1 & *el_ptr_2)
  3175. return 1;
  3176. if (!check_presence_pattern_sets (cycle_ptr_1, cycle_ptr_2, FALSE))
  3177. return 1;
  3178. if (!check_presence_pattern_sets (temp_reserv + (cycle_ptr_2
  3179. - operand_2),
  3180. cycle_ptr_2, TRUE))
  3181. return 1;
  3182. if (!check_absence_pattern_sets (cycle_ptr_1, cycle_ptr_2, FALSE))
  3183. return 1;
  3184. if (!check_absence_pattern_sets (temp_reserv + (cycle_ptr_2 - operand_2),
  3185. cycle_ptr_2, TRUE))
  3186. return 1;
  3187. }
  3188. return 0;
  3189. }
  3190. /* The function sets up RESULT bits by bits of OPERAND shifted on one
  3191. cpu cycle. The remaining bits of OPERAND (representing the last
  3192. cycle unit reservations) are not changed. */
  3193. static void
  3194. reserv_sets_shift (reserv_sets_t result, reserv_sets_t operand)
  3195. {
  3196. int i;
  3197. gcc_assert (result && operand && result != operand);
  3198. for (i = els_in_cycle_reserv; i < els_in_reservs; i++)
  3199. result [i - els_in_cycle_reserv] = operand [i];
  3200. }
  3201. /* OR of the reservation sets. */
  3202. static void
  3203. reserv_sets_or (reserv_sets_t result, reserv_sets_t operand_1,
  3204. reserv_sets_t operand_2)
  3205. {
  3206. set_el_t *el_ptr_1;
  3207. set_el_t *el_ptr_2;
  3208. set_el_t *result_set_el_ptr;
  3209. gcc_assert (result && operand_1 && operand_2);
  3210. for (el_ptr_1 = operand_1, el_ptr_2 = operand_2, result_set_el_ptr = result;
  3211. el_ptr_1 < operand_1 + els_in_reservs;
  3212. el_ptr_1++, el_ptr_2++, result_set_el_ptr++)
  3213. *result_set_el_ptr = *el_ptr_1 | *el_ptr_2;
  3214. }
  3215. /* AND of the reservation sets. */
  3216. static void
  3217. reserv_sets_and (reserv_sets_t result, reserv_sets_t operand_1,
  3218. reserv_sets_t operand_2)
  3219. {
  3220. set_el_t *el_ptr_1;
  3221. set_el_t *el_ptr_2;
  3222. set_el_t *result_set_el_ptr;
  3223. gcc_assert (result && operand_1 && operand_2);
  3224. for (el_ptr_1 = operand_1, el_ptr_2 = operand_2, result_set_el_ptr = result;
  3225. el_ptr_1 < operand_1 + els_in_reservs;
  3226. el_ptr_1++, el_ptr_2++, result_set_el_ptr++)
  3227. *result_set_el_ptr = *el_ptr_1 & *el_ptr_2;
  3228. }
  3229. /* The function outputs string representation of units reservation on
  3230. cycle START_CYCLE in the reservation set. The function uses repeat
  3231. construction if REPETITION_NUM > 1. */
  3232. static void
  3233. output_cycle_reservs (FILE *f, reserv_sets_t reservs, int start_cycle,
  3234. int repetition_num)
  3235. {
  3236. int unit_num;
  3237. int reserved_units_num;
  3238. reserved_units_num = 0;
  3239. for (unit_num = 0; unit_num < description->units_num; unit_num++)
  3240. if (bitmap_bit_p (reservs, start_cycle * els_in_cycle_reserv
  3241. * sizeof (set_el_t) * CHAR_BIT + unit_num))
  3242. reserved_units_num++;
  3243. gcc_assert (repetition_num > 0);
  3244. if (repetition_num != 1 && reserved_units_num > 1)
  3245. fprintf (f, "(");
  3246. reserved_units_num = 0;
  3247. for (unit_num = 0;
  3248. unit_num < description->units_num;
  3249. unit_num++)
  3250. if (bitmap_bit_p (reservs, start_cycle * els_in_cycle_reserv
  3251. * sizeof (set_el_t) * CHAR_BIT + unit_num))
  3252. {
  3253. if (reserved_units_num != 0)
  3254. fprintf (f, "+");
  3255. reserved_units_num++;
  3256. fprintf (f, "%s", units_array [unit_num]->name);
  3257. }
  3258. if (reserved_units_num == 0)
  3259. fprintf (f, NOTHING_NAME);
  3260. gcc_assert (repetition_num > 0);
  3261. if (repetition_num != 1 && reserved_units_num > 1)
  3262. fprintf (f, ")");
  3263. if (repetition_num != 1)
  3264. fprintf (f, "*%d", repetition_num);
  3265. }
  3266. /* The function outputs string representation of units reservation in
  3267. the reservation set. */
  3268. static void
  3269. output_reserv_sets (FILE *f, reserv_sets_t reservs)
  3270. {
  3271. int start_cycle = 0;
  3272. int cycle;
  3273. int repetition_num;
  3274. repetition_num = 0;
  3275. for (cycle = 0; cycle < max_cycles_num; cycle++)
  3276. if (repetition_num == 0)
  3277. {
  3278. repetition_num++;
  3279. start_cycle = cycle;
  3280. }
  3281. else if (memcmp
  3282. ((char *) reservs + start_cycle * els_in_cycle_reserv
  3283. * sizeof (set_el_t),
  3284. (char *) reservs + cycle * els_in_cycle_reserv
  3285. * sizeof (set_el_t),
  3286. els_in_cycle_reserv * sizeof (set_el_t)) == 0)
  3287. repetition_num++;
  3288. else
  3289. {
  3290. if (start_cycle != 0)
  3291. fprintf (f, ", ");
  3292. output_cycle_reservs (f, reservs, start_cycle, repetition_num);
  3293. repetition_num = 1;
  3294. start_cycle = cycle;
  3295. }
  3296. if (start_cycle < max_cycles_num)
  3297. {
  3298. if (start_cycle != 0)
  3299. fprintf (f, ", ");
  3300. output_cycle_reservs (f, reservs, start_cycle, repetition_num);
  3301. }
  3302. }
  3303. /* The following function returns free node state for AUTOMATON. It
  3304. may be new allocated node or node freed earlier. The function also
  3305. allocates reservation set if WITH_RESERVS has nonzero value. */
  3306. static state_t
  3307. get_free_state (int with_reservs, automaton_t automaton)
  3308. {
  3309. state_t result;
  3310. gcc_assert (max_cycles_num > 0 && automaton);
  3311. if (first_free_state)
  3312. {
  3313. result = first_free_state;
  3314. first_free_state = result->next_equiv_class_state;
  3315. result->next_equiv_class_state = NULL;
  3316. result->automaton = automaton;
  3317. result->first_out_arc = NULL;
  3318. result->it_was_placed_in_stack_for_NDFA_forming = 0;
  3319. result->it_was_placed_in_stack_for_DFA_forming = 0;
  3320. result->component_states = NULL;
  3321. }
  3322. else
  3323. {
  3324. #ifndef NDEBUG
  3325. allocated_states_num++;
  3326. #endif
  3327. result = XCREATENODE (struct state);
  3328. result->automaton = automaton;
  3329. result->first_out_arc = NULL;
  3330. result->unique_num = curr_unique_state_num;
  3331. curr_unique_state_num++;
  3332. }
  3333. if (with_reservs)
  3334. {
  3335. if (result->reservs == NULL)
  3336. result->reservs = alloc_empty_reserv_sets ();
  3337. else
  3338. memset (result->reservs, 0, els_in_reservs * sizeof (set_el_t));
  3339. }
  3340. return result;
  3341. }
  3342. /* The function frees node STATE. */
  3343. static void
  3344. free_state (state_t state)
  3345. {
  3346. free_alt_states (state->component_states);
  3347. state->next_equiv_class_state = first_free_state;
  3348. first_free_state = state;
  3349. }
  3350. /* Hash value of STATE. If STATE represents deterministic state it is
  3351. simply hash value of the corresponding reservation set. Otherwise
  3352. it is formed from hash values of the component deterministic
  3353. states. One more key is order number of state automaton. */
  3354. static hashval_t
  3355. state_hash (const void *state)
  3356. {
  3357. unsigned int hash_value;
  3358. alt_state_t alt_state;
  3359. if (((const_state_t) state)->component_states == NULL)
  3360. hash_value = reserv_sets_hash_value (((const_state_t) state)->reservs);
  3361. else
  3362. {
  3363. hash_value = 0;
  3364. for (alt_state = ((const_state_t) state)->component_states;
  3365. alt_state != NULL;
  3366. alt_state = alt_state->next_sorted_alt_state)
  3367. hash_value = (((hash_value >> (sizeof (unsigned) - 1) * CHAR_BIT)
  3368. | (hash_value << CHAR_BIT))
  3369. + alt_state->state->unique_num);
  3370. }
  3371. hash_value = (((hash_value >> (sizeof (unsigned) - 1) * CHAR_BIT)
  3372. | (hash_value << CHAR_BIT))
  3373. + ((const_state_t) state)->automaton->automaton_order_num);
  3374. return hash_value;
  3375. }
  3376. /* Return nonzero value if the states are the same. */
  3377. static int
  3378. state_eq_p (const void *state_1, const void *state_2)
  3379. {
  3380. alt_state_t alt_state_1;
  3381. alt_state_t alt_state_2;
  3382. if (((const_state_t) state_1)->automaton != ((const_state_t) state_2)->automaton)
  3383. return 0;
  3384. else if (((const_state_t) state_1)->component_states == NULL
  3385. && ((const_state_t) state_2)->component_states == NULL)
  3386. return reserv_sets_eq (((const_state_t) state_1)->reservs,
  3387. ((const_state_t) state_2)->reservs);
  3388. else if (((const_state_t) state_1)->component_states != NULL
  3389. && ((const_state_t) state_2)->component_states != NULL)
  3390. {
  3391. for (alt_state_1 = ((const_state_t) state_1)->component_states,
  3392. alt_state_2 = ((const_state_t) state_2)->component_states;
  3393. alt_state_1 != NULL && alt_state_2 != NULL;
  3394. alt_state_1 = alt_state_1->next_sorted_alt_state,
  3395. alt_state_2 = alt_state_2->next_sorted_alt_state)
  3396. /* All state in the list must be already in the hash table.
  3397. Also the lists must be sorted. */
  3398. if (alt_state_1->state != alt_state_2->state)
  3399. return 0;
  3400. return alt_state_1 == alt_state_2;
  3401. }
  3402. else
  3403. return 0;
  3404. }
  3405. /* Insert STATE into the state table. */
  3406. static state_t
  3407. insert_state (state_t state)
  3408. {
  3409. void **entry_ptr;
  3410. entry_ptr = htab_find_slot (state_table, (void *) state, INSERT);
  3411. if (*entry_ptr == NULL)
  3412. *entry_ptr = (void *) state;
  3413. return (state_t) *entry_ptr;
  3414. }
  3415. /* Add reservation of unit with UNIT_NUM on cycle CYCLE_NUM to
  3416. deterministic STATE. */
  3417. static void
  3418. set_state_reserv (state_t state, int cycle_num, int unit_num)
  3419. {
  3420. set_unit_reserv (state->reservs, cycle_num, unit_num);
  3421. }
  3422. /* Return nonzero value if the deterministic states contains a
  3423. reservation of the same cpu unit on the same cpu cycle. */
  3424. static int
  3425. intersected_state_reservs_p (state_t state1, state_t state2)
  3426. {
  3427. gcc_assert (state1->automaton == state2->automaton);
  3428. return reserv_sets_are_intersected (state1->reservs, state2->reservs);
  3429. }
  3430. /* Return deterministic state (inserted into the table) which
  3431. representing the automaton state which is union of reservations of
  3432. the deterministic states masked by RESERVS. */
  3433. static state_t
  3434. states_union (state_t state1, state_t state2, reserv_sets_t reservs)
  3435. {
  3436. state_t result;
  3437. state_t state_in_table;
  3438. gcc_assert (state1->automaton == state2->automaton);
  3439. result = get_free_state (1, state1->automaton);
  3440. reserv_sets_or (result->reservs, state1->reservs, state2->reservs);
  3441. reserv_sets_and (result->reservs, result->reservs, reservs);
  3442. state_in_table = insert_state (result);
  3443. if (result != state_in_table)
  3444. {
  3445. free_state (result);
  3446. result = state_in_table;
  3447. }
  3448. return result;
  3449. }
  3450. /* Return deterministic state (inserted into the table) which
  3451. represent the automaton state is obtained from deterministic STATE
  3452. by advancing cpu cycle and masking by RESERVS. */
  3453. static state_t
  3454. state_shift (state_t state, reserv_sets_t reservs)
  3455. {
  3456. state_t result;
  3457. state_t state_in_table;
  3458. result = get_free_state (1, state->automaton);
  3459. reserv_sets_shift (result->reservs, state->reservs);
  3460. reserv_sets_and (result->reservs, result->reservs, reservs);
  3461. state_in_table = insert_state (result);
  3462. if (result != state_in_table)
  3463. {
  3464. free_state (result);
  3465. result = state_in_table;
  3466. }
  3467. return result;
  3468. }
  3469. /* Initialization of the abstract data. */
  3470. static void
  3471. initiate_states (void)
  3472. {
  3473. decl_t decl;
  3474. int i;
  3475. if (description->units_num)
  3476. units_array = XNEWVEC (unit_decl_t, description->units_num);
  3477. else
  3478. units_array = 0;
  3479. for (i = 0; i < description->decls_num; i++)
  3480. {
  3481. decl = description->decls [i];
  3482. if (decl->mode == dm_unit)
  3483. units_array [DECL_UNIT (decl)->unit_num] = DECL_UNIT (decl);
  3484. }
  3485. max_cycles_num = description->max_insn_reserv_cycles;
  3486. els_in_cycle_reserv
  3487. = ((description->units_num + sizeof (set_el_t) * CHAR_BIT - 1)
  3488. / (sizeof (set_el_t) * CHAR_BIT));
  3489. els_in_reservs = els_in_cycle_reserv * max_cycles_num;
  3490. curr_unique_state_num = 0;
  3491. initiate_alt_states ();
  3492. state_table = htab_create (1500, state_hash, state_eq_p, (htab_del) 0);
  3493. temp_reserv = alloc_empty_reserv_sets ();
  3494. }
  3495. /* Finishing work with the abstract data. */
  3496. static void
  3497. finish_states (void)
  3498. {
  3499. free (units_array);
  3500. units_array = 0;
  3501. htab_delete (state_table);
  3502. first_free_state = NULL;
  3503. finish_alt_states ();
  3504. }
  3505. /* Abstract data `arcs'. */
  3506. /* List of free arcs. */
  3507. static arc_t first_free_arc;
  3508. #ifndef NDEBUG
  3509. /* The following variables is maximal number of allocated nodes
  3510. `arc'. */
  3511. static int allocated_arcs_num = 0;
  3512. #endif
  3513. /* The function frees node ARC. */
  3514. static void
  3515. free_arc (arc_t arc)
  3516. {
  3517. arc->next_out_arc = first_free_arc;
  3518. first_free_arc = arc;
  3519. }
  3520. /* The function removes and frees ARC staring from FROM_STATE. */
  3521. static void
  3522. remove_arc (state_t from_state, arc_t arc)
  3523. {
  3524. arc_t prev_arc;
  3525. arc_t curr_arc;
  3526. gcc_assert (arc);
  3527. for (prev_arc = NULL, curr_arc = from_state->first_out_arc;
  3528. curr_arc != NULL;
  3529. prev_arc = curr_arc, curr_arc = curr_arc->next_out_arc)
  3530. if (curr_arc == arc)
  3531. break;
  3532. gcc_assert (curr_arc);
  3533. if (prev_arc == NULL)
  3534. from_state->first_out_arc = arc->next_out_arc;
  3535. else
  3536. prev_arc->next_out_arc = arc->next_out_arc;
  3537. from_state->num_out_arcs--;
  3538. free_arc (arc);
  3539. }
  3540. /* The functions returns arc with given characteristics (or NULL if
  3541. the arc does not exist). */
  3542. static arc_t
  3543. find_arc (state_t from_state, state_t to_state, ainsn_t insn)
  3544. {
  3545. arc_t arc;
  3546. for (arc = first_out_arc (from_state); arc != NULL; arc = next_out_arc (arc))
  3547. if (arc->insn == insn
  3548. && (arc->to_state == to_state
  3549. || (collapse_flag
  3550. /* Any arc is good enough for a collapse-ndfa transition. */
  3551. && (insn->insn_reserv_decl
  3552. == DECL_INSN_RESERV (collapse_ndfa_insn_decl)))))
  3553. return arc;
  3554. return NULL;
  3555. }
  3556. /* The function adds arc from FROM_STATE to TO_STATE marked by AINSN,
  3557. unless such an arc already exists. */
  3558. static void
  3559. add_arc (state_t from_state, state_t to_state, ainsn_t ainsn)
  3560. {
  3561. arc_t new_arc;
  3562. new_arc = find_arc (from_state, to_state, ainsn);
  3563. if (new_arc != NULL)
  3564. return;
  3565. if (first_free_arc == NULL)
  3566. {
  3567. #ifndef NDEBUG
  3568. allocated_arcs_num++;
  3569. #endif
  3570. new_arc = XCREATENODE (struct arc);
  3571. new_arc->to_state = NULL;
  3572. new_arc->insn = NULL;
  3573. new_arc->next_out_arc = NULL;
  3574. }
  3575. else
  3576. {
  3577. new_arc = first_free_arc;
  3578. first_free_arc = first_free_arc->next_out_arc;
  3579. }
  3580. new_arc->to_state = to_state;
  3581. new_arc->insn = ainsn;
  3582. ainsn->arc_exists_p = 1;
  3583. new_arc->next_out_arc = from_state->first_out_arc;
  3584. from_state->first_out_arc = new_arc;
  3585. from_state->num_out_arcs++;
  3586. new_arc->next_arc_marked_by_insn = NULL;
  3587. }
  3588. /* The function returns the first arc starting from STATE. */
  3589. static arc_t
  3590. first_out_arc (const_state_t state)
  3591. {
  3592. return state->first_out_arc;
  3593. }
  3594. /* The function returns next out arc after ARC. */
  3595. static arc_t
  3596. next_out_arc (arc_t arc)
  3597. {
  3598. return arc->next_out_arc;
  3599. }
  3600. /* Initialization of the abstract data. */
  3601. static void
  3602. initiate_arcs (void)
  3603. {
  3604. first_free_arc = NULL;
  3605. }
  3606. /* Finishing work with the abstract data. */
  3607. static void
  3608. finish_arcs (void)
  3609. {
  3610. }
  3611. /* Abstract data `automata lists'. */
  3612. /* List of free states. */
  3613. static automata_list_el_t first_free_automata_list_el;
  3614. /* The list being formed. */
  3615. static automata_list_el_t current_automata_list;
  3616. /* Hash table of automata lists. */
  3617. static htab_t automata_list_table;
  3618. /* The following function returns free automata list el. It may be
  3619. new allocated node or node freed earlier. */
  3620. static automata_list_el_t
  3621. get_free_automata_list_el (void)
  3622. {
  3623. automata_list_el_t result;
  3624. if (first_free_automata_list_el != NULL)
  3625. {
  3626. result = first_free_automata_list_el;
  3627. first_free_automata_list_el
  3628. = first_free_automata_list_el->next_automata_list_el;
  3629. }
  3630. else
  3631. result = XCREATENODE (struct automata_list_el);
  3632. result->automaton = NULL;
  3633. result->next_automata_list_el = NULL;
  3634. return result;
  3635. }
  3636. /* The function frees node AUTOMATA_LIST_EL. */
  3637. static void
  3638. free_automata_list_el (automata_list_el_t automata_list_el)
  3639. {
  3640. if (automata_list_el == NULL)
  3641. return;
  3642. automata_list_el->next_automata_list_el = first_free_automata_list_el;
  3643. first_free_automata_list_el = automata_list_el;
  3644. }
  3645. /* The function frees list AUTOMATA_LIST. */
  3646. static void
  3647. free_automata_list (automata_list_el_t automata_list)
  3648. {
  3649. automata_list_el_t curr_automata_list_el;
  3650. automata_list_el_t next_automata_list_el;
  3651. for (curr_automata_list_el = automata_list;
  3652. curr_automata_list_el != NULL;
  3653. curr_automata_list_el = next_automata_list_el)
  3654. {
  3655. next_automata_list_el = curr_automata_list_el->next_automata_list_el;
  3656. free_automata_list_el (curr_automata_list_el);
  3657. }
  3658. }
  3659. /* Hash value of AUTOMATA_LIST. */
  3660. static hashval_t
  3661. automata_list_hash (const void *automata_list)
  3662. {
  3663. unsigned int hash_value;
  3664. const_automata_list_el_t curr_automata_list_el;
  3665. hash_value = 0;
  3666. for (curr_automata_list_el = (const_automata_list_el_t) automata_list;
  3667. curr_automata_list_el != NULL;
  3668. curr_automata_list_el = curr_automata_list_el->next_automata_list_el)
  3669. hash_value = (((hash_value >> (sizeof (unsigned) - 1) * CHAR_BIT)
  3670. | (hash_value << CHAR_BIT))
  3671. + curr_automata_list_el->automaton->automaton_order_num);
  3672. return hash_value;
  3673. }
  3674. /* Return nonzero value if the automata_lists are the same. */
  3675. static int
  3676. automata_list_eq_p (const void *automata_list_1, const void *automata_list_2)
  3677. {
  3678. const_automata_list_el_t automata_list_el_1;
  3679. const_automata_list_el_t automata_list_el_2;
  3680. for (automata_list_el_1 = (const_automata_list_el_t) automata_list_1,
  3681. automata_list_el_2 = (const_automata_list_el_t) automata_list_2;
  3682. automata_list_el_1 != NULL && automata_list_el_2 != NULL;
  3683. automata_list_el_1 = automata_list_el_1->next_automata_list_el,
  3684. automata_list_el_2 = automata_list_el_2->next_automata_list_el)
  3685. if (automata_list_el_1->automaton != automata_list_el_2->automaton)
  3686. return 0;
  3687. return automata_list_el_1 == automata_list_el_2;
  3688. }
  3689. /* Initialization of the abstract data. */
  3690. static void
  3691. initiate_automata_lists (void)
  3692. {
  3693. first_free_automata_list_el = NULL;
  3694. automata_list_table = htab_create (1500, automata_list_hash,
  3695. automata_list_eq_p, (htab_del) 0);
  3696. }
  3697. /* The following function starts new automata list and makes it the
  3698. current one. */
  3699. static void
  3700. automata_list_start (void)
  3701. {
  3702. current_automata_list = NULL;
  3703. }
  3704. /* The following function adds AUTOMATON to the current list. */
  3705. static void
  3706. automata_list_add (automaton_t automaton)
  3707. {
  3708. automata_list_el_t el;
  3709. el = get_free_automata_list_el ();
  3710. el->automaton = automaton;
  3711. el->next_automata_list_el = current_automata_list;
  3712. current_automata_list = el;
  3713. }
  3714. /* The following function finishes forming the current list, inserts
  3715. it into the table and returns it. */
  3716. static automata_list_el_t
  3717. automata_list_finish (void)
  3718. {
  3719. void **entry_ptr;
  3720. if (current_automata_list == NULL)
  3721. return NULL;
  3722. entry_ptr = htab_find_slot (automata_list_table,
  3723. (void *) current_automata_list, INSERT);
  3724. if (*entry_ptr == NULL)
  3725. *entry_ptr = (void *) current_automata_list;
  3726. else
  3727. free_automata_list (current_automata_list);
  3728. current_automata_list = NULL;
  3729. return (automata_list_el_t) *entry_ptr;
  3730. }
  3731. /* Finishing work with the abstract data. */
  3732. static void
  3733. finish_automata_lists (void)
  3734. {
  3735. htab_delete (automata_list_table);
  3736. }
  3737. /* The page contains abstract data for work with exclusion sets (see
  3738. exclusion_set in file rtl.def). */
  3739. /* The following variable refers to an exclusion set returned by
  3740. get_excl_set. This is bit string of length equal to cpu units
  3741. number. If exclusion set for given unit contains 1 for a unit,
  3742. then simultaneous reservation of the units is prohibited. */
  3743. static reserv_sets_t excl_set;
  3744. /* The array contains exclusion sets for each unit. */
  3745. static reserv_sets_t *unit_excl_set_table;
  3746. /* The following function forms the array containing exclusion sets
  3747. for each unit. */
  3748. static void
  3749. initiate_excl_sets (void)
  3750. {
  3751. decl_t decl;
  3752. reserv_sets_t unit_excl_set;
  3753. unit_set_el_t el;
  3754. int i;
  3755. obstack_blank (&irp, els_in_cycle_reserv * sizeof (set_el_t));
  3756. excl_set = (reserv_sets_t) obstack_base (&irp);
  3757. obstack_finish (&irp);
  3758. obstack_blank (&irp, description->units_num * sizeof (reserv_sets_t));
  3759. unit_excl_set_table = (reserv_sets_t *) obstack_base (&irp);
  3760. obstack_finish (&irp);
  3761. /* Evaluate unit exclusion sets. */
  3762. for (i = 0; i < description->decls_num; i++)
  3763. {
  3764. decl = description->decls [i];
  3765. if (decl->mode == dm_unit)
  3766. {
  3767. obstack_blank (&irp, els_in_cycle_reserv * sizeof (set_el_t));
  3768. unit_excl_set = (reserv_sets_t) obstack_base (&irp);
  3769. obstack_finish (&irp);
  3770. memset (unit_excl_set, 0, els_in_cycle_reserv * sizeof (set_el_t));
  3771. for (el = DECL_UNIT (decl)->excl_list;
  3772. el != NULL;
  3773. el = el->next_unit_set_el)
  3774. {
  3775. bitmap_set_bit (unit_excl_set, el->unit_decl->unit_num);
  3776. el->unit_decl->in_set_p = TRUE;
  3777. }
  3778. unit_excl_set_table [DECL_UNIT (decl)->unit_num] = unit_excl_set;
  3779. }
  3780. }
  3781. }
  3782. /* The function sets up and return EXCL_SET which is union of
  3783. exclusion sets for each unit in IN_SET. */
  3784. static reserv_sets_t
  3785. get_excl_set (reserv_sets_t in_set)
  3786. {
  3787. int el;
  3788. unsigned int i;
  3789. int start_unit_num;
  3790. int unit_num;
  3791. memset (excl_set, 0, els_in_cycle_reserv * sizeof (set_el_t));
  3792. for (el = 0; el < els_in_cycle_reserv; el++)
  3793. if (in_set[el])
  3794. for (i = 0; i < CHAR_BIT * sizeof (set_el_t); i++)
  3795. if ((in_set[el] >> i) & 1)
  3796. {
  3797. start_unit_num = el * CHAR_BIT * sizeof (set_el_t) + i;
  3798. if (start_unit_num >= description->units_num)
  3799. return excl_set;
  3800. for (unit_num = 0; unit_num < els_in_cycle_reserv; unit_num++)
  3801. {
  3802. excl_set [unit_num]
  3803. |= unit_excl_set_table [start_unit_num] [unit_num];
  3804. }
  3805. }
  3806. return excl_set;
  3807. }
  3808. /* The page contains abstract data for work with presence/absence
  3809. pattern sets (see presence_set/absence_set in file rtl.def). */
  3810. /* The following arrays contain correspondingly presence, final
  3811. presence, absence, and final absence patterns for each unit. */
  3812. static pattern_reserv_t *unit_presence_set_table;
  3813. static pattern_reserv_t *unit_final_presence_set_table;
  3814. static pattern_reserv_t *unit_absence_set_table;
  3815. static pattern_reserv_t *unit_final_absence_set_table;
  3816. /* The following function forms list of reservation sets for given
  3817. PATTERN_LIST. */
  3818. static pattern_reserv_t
  3819. form_reserv_sets_list (pattern_set_el_t pattern_list)
  3820. {
  3821. pattern_set_el_t el;
  3822. pattern_reserv_t first, curr, prev;
  3823. int i;
  3824. prev = first = NULL;
  3825. for (el = pattern_list; el != NULL; el = el->next_pattern_set_el)
  3826. {
  3827. curr = XCREATENODE (struct pattern_reserv);
  3828. curr->reserv = alloc_empty_reserv_sets ();
  3829. curr->next_pattern_reserv = NULL;
  3830. for (i = 0; i < el->units_num; i++)
  3831. {
  3832. bitmap_set_bit (curr->reserv, el->unit_decls [i]->unit_num);
  3833. el->unit_decls [i]->in_set_p = TRUE;
  3834. }
  3835. if (prev != NULL)
  3836. prev->next_pattern_reserv = curr;
  3837. else
  3838. first = curr;
  3839. prev = curr;
  3840. }
  3841. return first;
  3842. }
  3843. /* The following function forms the array containing presence and
  3844. absence pattern sets for each unit. */
  3845. static void
  3846. initiate_presence_absence_pattern_sets (void)
  3847. {
  3848. decl_t decl;
  3849. int i;
  3850. obstack_blank (&irp, description->units_num * sizeof (pattern_reserv_t));
  3851. unit_presence_set_table = (pattern_reserv_t *) obstack_base (&irp);
  3852. obstack_finish (&irp);
  3853. obstack_blank (&irp, description->units_num * sizeof (pattern_reserv_t));
  3854. unit_final_presence_set_table = (pattern_reserv_t *) obstack_base (&irp);
  3855. obstack_finish (&irp);
  3856. obstack_blank (&irp, description->units_num * sizeof (pattern_reserv_t));
  3857. unit_absence_set_table = (pattern_reserv_t *) obstack_base (&irp);
  3858. obstack_finish (&irp);
  3859. obstack_blank (&irp, description->units_num * sizeof (pattern_reserv_t));
  3860. unit_final_absence_set_table = (pattern_reserv_t *) obstack_base (&irp);
  3861. obstack_finish (&irp);
  3862. /* Evaluate unit presence/absence sets. */
  3863. for (i = 0; i < description->decls_num; i++)
  3864. {
  3865. decl = description->decls [i];
  3866. if (decl->mode == dm_unit)
  3867. {
  3868. unit_presence_set_table [DECL_UNIT (decl)->unit_num]
  3869. = form_reserv_sets_list (DECL_UNIT (decl)->presence_list);
  3870. unit_final_presence_set_table [DECL_UNIT (decl)->unit_num]
  3871. = form_reserv_sets_list (DECL_UNIT (decl)->final_presence_list);
  3872. unit_absence_set_table [DECL_UNIT (decl)->unit_num]
  3873. = form_reserv_sets_list (DECL_UNIT (decl)->absence_list);
  3874. unit_final_absence_set_table [DECL_UNIT (decl)->unit_num]
  3875. = form_reserv_sets_list (DECL_UNIT (decl)->final_absence_list);
  3876. }
  3877. }
  3878. }
  3879. /* The function checks that CHECKED_SET satisfies all presence pattern
  3880. sets for units in ORIGINAL_SET. The function returns TRUE if it
  3881. is ok. */
  3882. static int
  3883. check_presence_pattern_sets (reserv_sets_t checked_set,
  3884. reserv_sets_t original_set,
  3885. int final_p)
  3886. {
  3887. int el;
  3888. unsigned int i;
  3889. int start_unit_num;
  3890. int unit_num;
  3891. int presence_p;
  3892. pattern_reserv_t pat_reserv;
  3893. for (el = 0; el < els_in_cycle_reserv; el++)
  3894. if (original_set[el])
  3895. for (i = 0; i < CHAR_BIT * sizeof (set_el_t); i++)
  3896. if ((original_set[el] >> i) & 1)
  3897. {
  3898. start_unit_num = el * CHAR_BIT * sizeof (set_el_t) + i;
  3899. if (start_unit_num >= description->units_num)
  3900. break;
  3901. if ((final_p
  3902. && unit_final_presence_set_table [start_unit_num] == NULL)
  3903. || (!final_p
  3904. && unit_presence_set_table [start_unit_num] == NULL))
  3905. continue;
  3906. presence_p = FALSE;
  3907. for (pat_reserv = (final_p
  3908. ? unit_final_presence_set_table [start_unit_num]
  3909. : unit_presence_set_table [start_unit_num]);
  3910. pat_reserv != NULL;
  3911. pat_reserv = pat_reserv->next_pattern_reserv)
  3912. {
  3913. for (unit_num = 0; unit_num < els_in_cycle_reserv; unit_num++)
  3914. if ((checked_set [unit_num] & pat_reserv->reserv [unit_num])
  3915. != pat_reserv->reserv [unit_num])
  3916. break;
  3917. presence_p = presence_p || unit_num >= els_in_cycle_reserv;
  3918. }
  3919. if (!presence_p)
  3920. return FALSE;
  3921. }
  3922. return TRUE;
  3923. }
  3924. /* The function checks that CHECKED_SET satisfies all absence pattern
  3925. sets for units in ORIGINAL_SET. The function returns TRUE if it
  3926. is ok. */
  3927. static int
  3928. check_absence_pattern_sets (reserv_sets_t checked_set,
  3929. reserv_sets_t original_set,
  3930. int final_p)
  3931. {
  3932. int el;
  3933. unsigned int i;
  3934. int start_unit_num;
  3935. int unit_num;
  3936. pattern_reserv_t pat_reserv;
  3937. for (el = 0; el < els_in_cycle_reserv; el++)
  3938. if (original_set[el])
  3939. for (i = 0; i < CHAR_BIT * sizeof (set_el_t); i++)
  3940. if ((original_set[el] >> i) & 1)
  3941. {
  3942. start_unit_num = el * CHAR_BIT * sizeof (set_el_t) + i;
  3943. if (start_unit_num >= description->units_num)
  3944. break;
  3945. for (pat_reserv = (final_p
  3946. ? unit_final_absence_set_table [start_unit_num]
  3947. : unit_absence_set_table [start_unit_num]);
  3948. pat_reserv != NULL;
  3949. pat_reserv = pat_reserv->next_pattern_reserv)
  3950. {
  3951. for (unit_num = 0; unit_num < els_in_cycle_reserv; unit_num++)
  3952. if ((checked_set [unit_num] & pat_reserv->reserv [unit_num])
  3953. != pat_reserv->reserv [unit_num]
  3954. && pat_reserv->reserv [unit_num])
  3955. break;
  3956. if (unit_num >= els_in_cycle_reserv)
  3957. return FALSE;
  3958. }
  3959. }
  3960. return TRUE;
  3961. }
  3962. /* This page contains code for transformation of original reservations
  3963. described in .md file. The main goal of transformations is
  3964. simplifying reservation and lifting up all `|' on the top of IR
  3965. reservation representation. */
  3966. /* The following function makes copy of IR representation of
  3967. reservation. The function also substitutes all reservations
  3968. defined by define_reservation by corresponding value during making
  3969. the copy. */
  3970. static regexp_t
  3971. copy_insn_regexp (regexp_t regexp)
  3972. {
  3973. regexp_t result;
  3974. int i;
  3975. switch (regexp->mode)
  3976. {
  3977. case rm_reserv:
  3978. result = copy_insn_regexp (REGEXP_RESERV (regexp)->reserv_decl->regexp);
  3979. break;
  3980. case rm_unit:
  3981. result = XCOPYNODE (struct regexp, regexp);
  3982. break;
  3983. case rm_repeat:
  3984. result = XCOPYNODE (struct regexp, regexp);
  3985. REGEXP_REPEAT (result)->regexp
  3986. = copy_insn_regexp (REGEXP_REPEAT (regexp)->regexp);
  3987. break;
  3988. case rm_sequence:
  3989. result = XCOPYNODEVAR (struct regexp, regexp,
  3990. sizeof (struct regexp) + sizeof (regexp_t)
  3991. * (REGEXP_SEQUENCE (regexp)->regexps_num - 1));
  3992. for (i = 0; i <REGEXP_SEQUENCE (regexp)->regexps_num; i++)
  3993. REGEXP_SEQUENCE (result)->regexps [i]
  3994. = copy_insn_regexp (REGEXP_SEQUENCE (regexp)->regexps [i]);
  3995. break;
  3996. case rm_allof:
  3997. result = XCOPYNODEVAR (struct regexp, regexp,
  3998. sizeof (struct regexp) + sizeof (regexp_t)
  3999. * (REGEXP_ALLOF (regexp)->regexps_num - 1));
  4000. for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
  4001. REGEXP_ALLOF (result)->regexps [i]
  4002. = copy_insn_regexp (REGEXP_ALLOF (regexp)->regexps [i]);
  4003. break;
  4004. case rm_oneof:
  4005. result = XCOPYNODEVAR (struct regexp, regexp,
  4006. sizeof (struct regexp) + sizeof (regexp_t)
  4007. * (REGEXP_ONEOF (regexp)->regexps_num - 1));
  4008. for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
  4009. REGEXP_ONEOF (result)->regexps [i]
  4010. = copy_insn_regexp (REGEXP_ONEOF (regexp)->regexps [i]);
  4011. break;
  4012. case rm_nothing:
  4013. result = XCOPYNODE (struct regexp, regexp);
  4014. break;
  4015. default:
  4016. gcc_unreachable ();
  4017. }
  4018. return result;
  4019. }
  4020. /* The following variable is set up 1 if a transformation has been
  4021. applied. */
  4022. static int regexp_transformed_p;
  4023. /* The function makes transformation
  4024. A*N -> A, A, ... */
  4025. static regexp_t
  4026. transform_1 (regexp_t regexp)
  4027. {
  4028. int i;
  4029. int repeat_num;
  4030. regexp_t operand;
  4031. pos_t pos;
  4032. if (regexp->mode == rm_repeat)
  4033. {
  4034. repeat_num = REGEXP_REPEAT (regexp)->repeat_num;
  4035. gcc_assert (repeat_num > 1);
  4036. operand = REGEXP_REPEAT (regexp)->regexp;
  4037. pos = regexp->mode;
  4038. regexp = XCREATENODEVAR (struct regexp, sizeof (struct regexp)
  4039. + sizeof (regexp_t) * (repeat_num - 1));
  4040. regexp->mode = rm_sequence;
  4041. regexp->pos = pos;
  4042. REGEXP_SEQUENCE (regexp)->regexps_num = repeat_num;
  4043. for (i = 0; i < repeat_num; i++)
  4044. REGEXP_SEQUENCE (regexp)->regexps [i] = copy_insn_regexp (operand);
  4045. regexp_transformed_p = 1;
  4046. }
  4047. return regexp;
  4048. }
  4049. /* The function makes transformations
  4050. ...,(A,B,...),C,... -> ...,A,B,...,C,...
  4051. ...+(A+B+...)+C+... -> ...+A+B+...+C+...
  4052. ...|(A|B|...)|C|... -> ...|A|B|...|C|... */
  4053. static regexp_t
  4054. transform_2 (regexp_t regexp)
  4055. {
  4056. if (regexp->mode == rm_sequence)
  4057. {
  4058. regexp_t sequence = NULL;
  4059. regexp_t result;
  4060. int sequence_index = 0;
  4061. int i, j;
  4062. for (i = 0; i < REGEXP_SEQUENCE (regexp)->regexps_num; i++)
  4063. if (REGEXP_SEQUENCE (regexp)->regexps [i]->mode == rm_sequence)
  4064. {
  4065. sequence_index = i;
  4066. sequence = REGEXP_SEQUENCE (regexp)->regexps [i];
  4067. break;
  4068. }
  4069. if (i < REGEXP_SEQUENCE (regexp)->regexps_num)
  4070. {
  4071. gcc_assert (REGEXP_SEQUENCE (sequence)->regexps_num > 1
  4072. && REGEXP_SEQUENCE (regexp)->regexps_num > 1);
  4073. result = XCREATENODEVAR (struct regexp, sizeof (struct regexp)
  4074. + sizeof (regexp_t)
  4075. * (REGEXP_SEQUENCE (regexp)->regexps_num
  4076. + REGEXP_SEQUENCE (sequence)->regexps_num
  4077. - 2));
  4078. result->mode = rm_sequence;
  4079. result->pos = regexp->pos;
  4080. REGEXP_SEQUENCE (result)->regexps_num
  4081. = (REGEXP_SEQUENCE (regexp)->regexps_num
  4082. + REGEXP_SEQUENCE (sequence)->regexps_num - 1);
  4083. for (i = 0; i < REGEXP_SEQUENCE (regexp)->regexps_num; i++)
  4084. if (i < sequence_index)
  4085. REGEXP_SEQUENCE (result)->regexps [i]
  4086. = copy_insn_regexp (REGEXP_SEQUENCE (regexp)->regexps [i]);
  4087. else if (i > sequence_index)
  4088. REGEXP_SEQUENCE (result)->regexps
  4089. [i + REGEXP_SEQUENCE (sequence)->regexps_num - 1]
  4090. = copy_insn_regexp (REGEXP_SEQUENCE (regexp)->regexps [i]);
  4091. else
  4092. for (j = 0; j < REGEXP_SEQUENCE (sequence)->regexps_num; j++)
  4093. REGEXP_SEQUENCE (result)->regexps [i + j]
  4094. = copy_insn_regexp (REGEXP_SEQUENCE (sequence)->regexps [j]);
  4095. regexp_transformed_p = 1;
  4096. regexp = result;
  4097. }
  4098. }
  4099. else if (regexp->mode == rm_allof)
  4100. {
  4101. regexp_t allof = NULL;
  4102. regexp_t result;
  4103. int allof_index = 0;
  4104. int i, j;
  4105. for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
  4106. if (REGEXP_ALLOF (regexp)->regexps [i]->mode == rm_allof)
  4107. {
  4108. allof_index = i;
  4109. allof = REGEXP_ALLOF (regexp)->regexps [i];
  4110. break;
  4111. }
  4112. if (i < REGEXP_ALLOF (regexp)->regexps_num)
  4113. {
  4114. gcc_assert (REGEXP_ALLOF (allof)->regexps_num > 1
  4115. && REGEXP_ALLOF (regexp)->regexps_num > 1);
  4116. result = XCREATENODEVAR (struct regexp, sizeof (struct regexp)
  4117. + sizeof (regexp_t)
  4118. * (REGEXP_ALLOF (regexp)->regexps_num
  4119. + REGEXP_ALLOF (allof)->regexps_num - 2));
  4120. result->mode = rm_allof;
  4121. result->pos = regexp->pos;
  4122. REGEXP_ALLOF (result)->regexps_num
  4123. = (REGEXP_ALLOF (regexp)->regexps_num
  4124. + REGEXP_ALLOF (allof)->regexps_num - 1);
  4125. for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
  4126. if (i < allof_index)
  4127. REGEXP_ALLOF (result)->regexps [i]
  4128. = copy_insn_regexp (REGEXP_ALLOF (regexp)->regexps [i]);
  4129. else if (i > allof_index)
  4130. REGEXP_ALLOF (result)->regexps
  4131. [i + REGEXP_ALLOF (allof)->regexps_num - 1]
  4132. = copy_insn_regexp (REGEXP_ALLOF (regexp)->regexps [i]);
  4133. else
  4134. for (j = 0; j < REGEXP_ALLOF (allof)->regexps_num; j++)
  4135. REGEXP_ALLOF (result)->regexps [i + j]
  4136. = copy_insn_regexp (REGEXP_ALLOF (allof)->regexps [j]);
  4137. regexp_transformed_p = 1;
  4138. regexp = result;
  4139. }
  4140. }
  4141. else if (regexp->mode == rm_oneof)
  4142. {
  4143. regexp_t oneof = NULL;
  4144. regexp_t result;
  4145. int oneof_index = 0;
  4146. int i, j;
  4147. for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
  4148. if (REGEXP_ONEOF (regexp)->regexps [i]->mode == rm_oneof)
  4149. {
  4150. oneof_index = i;
  4151. oneof = REGEXP_ONEOF (regexp)->regexps [i];
  4152. break;
  4153. }
  4154. if (i < REGEXP_ONEOF (regexp)->regexps_num)
  4155. {
  4156. gcc_assert (REGEXP_ONEOF (oneof)->regexps_num > 1
  4157. && REGEXP_ONEOF (regexp)->regexps_num > 1);
  4158. result = XCREATENODEVAR (struct regexp, sizeof (struct regexp)
  4159. + sizeof (regexp_t)
  4160. * (REGEXP_ONEOF (regexp)->regexps_num
  4161. + REGEXP_ONEOF (oneof)->regexps_num - 2));
  4162. result->mode = rm_oneof;
  4163. result->pos = regexp->pos;
  4164. REGEXP_ONEOF (result)->regexps_num
  4165. = (REGEXP_ONEOF (regexp)->regexps_num
  4166. + REGEXP_ONEOF (oneof)->regexps_num - 1);
  4167. for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
  4168. if (i < oneof_index)
  4169. REGEXP_ONEOF (result)->regexps [i]
  4170. = copy_insn_regexp (REGEXP_ONEOF (regexp)->regexps [i]);
  4171. else if (i > oneof_index)
  4172. REGEXP_ONEOF (result)->regexps
  4173. [i + REGEXP_ONEOF (oneof)->regexps_num - 1]
  4174. = copy_insn_regexp (REGEXP_ONEOF (regexp)->regexps [i]);
  4175. else
  4176. for (j = 0; j < REGEXP_ONEOF (oneof)->regexps_num; j++)
  4177. REGEXP_ONEOF (result)->regexps [i + j]
  4178. = copy_insn_regexp (REGEXP_ONEOF (oneof)->regexps [j]);
  4179. regexp_transformed_p = 1;
  4180. regexp = result;
  4181. }
  4182. }
  4183. return regexp;
  4184. }
  4185. /* The function makes transformations
  4186. ...,A|B|...,C,... -> (...,A,C,...)|(...,B,C,...)|...
  4187. ...+(A|B|...)+C+... -> (...+A+C+...)|(...+B+C+...)|...
  4188. ...+(A,B,...)+C+... -> (...+A+C+...),B,...
  4189. ...+(A,B,...)+(C,D,...) -> (A+C),(B+D),... */
  4190. static regexp_t
  4191. transform_3 (regexp_t regexp)
  4192. {
  4193. if (regexp->mode == rm_sequence)
  4194. {
  4195. regexp_t oneof = NULL;
  4196. int oneof_index = 0;
  4197. regexp_t result;
  4198. regexp_t sequence;
  4199. int i, j;
  4200. for (i = 0; i <REGEXP_SEQUENCE (regexp)->regexps_num; i++)
  4201. if (REGEXP_SEQUENCE (regexp)->regexps [i]->mode == rm_oneof)
  4202. {
  4203. oneof_index = i;
  4204. oneof = REGEXP_SEQUENCE (regexp)->regexps [i];
  4205. break;
  4206. }
  4207. if (i < REGEXP_SEQUENCE (regexp)->regexps_num)
  4208. {
  4209. gcc_assert (REGEXP_ONEOF (oneof)->regexps_num > 1
  4210. && REGEXP_SEQUENCE (regexp)->regexps_num > 1);
  4211. result = XCREATENODEVAR (struct regexp, sizeof (struct regexp)
  4212. + sizeof (regexp_t)
  4213. * (REGEXP_ONEOF (oneof)->regexps_num - 1));
  4214. result->mode = rm_oneof;
  4215. result->pos = regexp->pos;
  4216. REGEXP_ONEOF (result)->regexps_num
  4217. = REGEXP_ONEOF (oneof)->regexps_num;
  4218. for (i = 0; i < REGEXP_ONEOF (result)->regexps_num; i++)
  4219. {
  4220. sequence
  4221. = XCREATENODEVAR (struct regexp, sizeof (struct regexp)
  4222. + sizeof (regexp_t)
  4223. * (REGEXP_SEQUENCE (regexp)->regexps_num - 1));
  4224. sequence->mode = rm_sequence;
  4225. sequence->pos = regexp->pos;
  4226. REGEXP_SEQUENCE (sequence)->regexps_num
  4227. = REGEXP_SEQUENCE (regexp)->regexps_num;
  4228. REGEXP_ONEOF (result)->regexps [i] = sequence;
  4229. for (j = 0; j < REGEXP_SEQUENCE (sequence)->regexps_num; j++)
  4230. if (j != oneof_index)
  4231. REGEXP_SEQUENCE (sequence)->regexps [j]
  4232. = copy_insn_regexp (REGEXP_SEQUENCE (regexp)->regexps [j]);
  4233. else
  4234. REGEXP_SEQUENCE (sequence)->regexps [j]
  4235. = copy_insn_regexp (REGEXP_ONEOF (oneof)->regexps [i]);
  4236. }
  4237. regexp_transformed_p = 1;
  4238. regexp = result;
  4239. }
  4240. }
  4241. else if (regexp->mode == rm_allof)
  4242. {
  4243. regexp_t oneof = NULL;
  4244. regexp_t seq;
  4245. int oneof_index = 0;
  4246. int max_seq_length, allof_length;
  4247. regexp_t result;
  4248. regexp_t allof = NULL;
  4249. regexp_t allof_op = NULL;
  4250. int i, j;
  4251. for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
  4252. if (REGEXP_ALLOF (regexp)->regexps [i]->mode == rm_oneof)
  4253. {
  4254. oneof_index = i;
  4255. oneof = REGEXP_ALLOF (regexp)->regexps [i];
  4256. break;
  4257. }
  4258. if (i < REGEXP_ALLOF (regexp)->regexps_num)
  4259. {
  4260. gcc_assert (REGEXP_ONEOF (oneof)->regexps_num > 1
  4261. && REGEXP_ALLOF (regexp)->regexps_num > 1);
  4262. result = XCREATENODEVAR (struct regexp, sizeof (struct regexp)
  4263. + sizeof (regexp_t)
  4264. * (REGEXP_ONEOF (oneof)->regexps_num - 1));
  4265. result->mode = rm_oneof;
  4266. result->pos = regexp->pos;
  4267. REGEXP_ONEOF (result)->regexps_num
  4268. = REGEXP_ONEOF (oneof)->regexps_num;
  4269. for (i = 0; i < REGEXP_ONEOF (result)->regexps_num; i++)
  4270. {
  4271. allof
  4272. = XCREATENODEVAR (struct regexp, sizeof (struct regexp)
  4273. + sizeof (regexp_t)
  4274. * (REGEXP_ALLOF (regexp)->regexps_num - 1));
  4275. allof->mode = rm_allof;
  4276. allof->pos = regexp->pos;
  4277. REGEXP_ALLOF (allof)->regexps_num
  4278. = REGEXP_ALLOF (regexp)->regexps_num;
  4279. REGEXP_ONEOF (result)->regexps [i] = allof;
  4280. for (j = 0; j < REGEXP_ALLOF (allof)->regexps_num; j++)
  4281. if (j != oneof_index)
  4282. REGEXP_ALLOF (allof)->regexps [j]
  4283. = copy_insn_regexp (REGEXP_ALLOF (regexp)->regexps [j]);
  4284. else
  4285. REGEXP_ALLOF (allof)->regexps [j]
  4286. = copy_insn_regexp (REGEXP_ONEOF (oneof)->regexps [i]);
  4287. }
  4288. regexp_transformed_p = 1;
  4289. regexp = result;
  4290. }
  4291. max_seq_length = 0;
  4292. if (regexp->mode == rm_allof)
  4293. for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
  4294. {
  4295. switch (REGEXP_ALLOF (regexp)->regexps [i]->mode)
  4296. {
  4297. case rm_sequence:
  4298. seq = REGEXP_ALLOF (regexp)->regexps [i];
  4299. if (max_seq_length < REGEXP_SEQUENCE (seq)->regexps_num)
  4300. max_seq_length = REGEXP_SEQUENCE (seq)->regexps_num;
  4301. break;
  4302. case rm_unit:
  4303. case rm_nothing:
  4304. break;
  4305. default:
  4306. max_seq_length = 0;
  4307. goto break_for;
  4308. }
  4309. }
  4310. break_for:
  4311. if (max_seq_length != 0)
  4312. {
  4313. gcc_assert (max_seq_length != 1
  4314. && REGEXP_ALLOF (regexp)->regexps_num > 1);
  4315. result = XCREATENODEVAR (struct regexp, sizeof (struct regexp)
  4316. + sizeof (regexp_t) * (max_seq_length - 1));
  4317. result->mode = rm_sequence;
  4318. result->pos = regexp->pos;
  4319. REGEXP_SEQUENCE (result)->regexps_num = max_seq_length;
  4320. for (i = 0; i < max_seq_length; i++)
  4321. {
  4322. allof_length = 0;
  4323. for (j = 0; j < REGEXP_ALLOF (regexp)->regexps_num; j++)
  4324. switch (REGEXP_ALLOF (regexp)->regexps [j]->mode)
  4325. {
  4326. case rm_sequence:
  4327. if (i < (REGEXP_SEQUENCE (REGEXP_ALLOF (regexp)
  4328. ->regexps [j])->regexps_num))
  4329. {
  4330. allof_op
  4331. = (REGEXP_SEQUENCE (REGEXP_ALLOF (regexp)
  4332. ->regexps [j])
  4333. ->regexps [i]);
  4334. allof_length++;
  4335. }
  4336. break;
  4337. case rm_unit:
  4338. case rm_nothing:
  4339. if (i == 0)
  4340. {
  4341. allof_op = REGEXP_ALLOF (regexp)->regexps [j];
  4342. allof_length++;
  4343. }
  4344. break;
  4345. default:
  4346. break;
  4347. }
  4348. if (allof_length == 1)
  4349. REGEXP_SEQUENCE (result)->regexps [i] = allof_op;
  4350. else
  4351. {
  4352. allof = XCREATENODEVAR (struct regexp, sizeof (struct regexp)
  4353. + sizeof (regexp_t)
  4354. * (allof_length - 1));
  4355. allof->mode = rm_allof;
  4356. allof->pos = regexp->pos;
  4357. REGEXP_ALLOF (allof)->regexps_num = allof_length;
  4358. REGEXP_SEQUENCE (result)->regexps [i] = allof;
  4359. allof_length = 0;
  4360. for (j = 0; j < REGEXP_ALLOF (regexp)->regexps_num; j++)
  4361. if (REGEXP_ALLOF (regexp)->regexps [j]->mode == rm_sequence
  4362. && (i <
  4363. (REGEXP_SEQUENCE (REGEXP_ALLOF (regexp)
  4364. ->regexps [j])->regexps_num)))
  4365. {
  4366. allof_op = (REGEXP_SEQUENCE (REGEXP_ALLOF (regexp)
  4367. ->regexps [j])
  4368. ->regexps [i]);
  4369. REGEXP_ALLOF (allof)->regexps [allof_length]
  4370. = allof_op;
  4371. allof_length++;
  4372. }
  4373. else if (i == 0
  4374. && (REGEXP_ALLOF (regexp)->regexps [j]->mode
  4375. == rm_unit
  4376. || (REGEXP_ALLOF (regexp)->regexps [j]->mode
  4377. == rm_nothing)))
  4378. {
  4379. allof_op = REGEXP_ALLOF (regexp)->regexps [j];
  4380. REGEXP_ALLOF (allof)->regexps [allof_length]
  4381. = allof_op;
  4382. allof_length++;
  4383. }
  4384. }
  4385. }
  4386. regexp_transformed_p = 1;
  4387. regexp = result;
  4388. }
  4389. }
  4390. return regexp;
  4391. }
  4392. /* The function traverses IR of reservation and applies transformations
  4393. implemented by FUNC. */
  4394. static regexp_t
  4395. regexp_transform_func (regexp_t regexp, regexp_t (*func) (regexp_t regexp))
  4396. {
  4397. int i;
  4398. switch (regexp->mode)
  4399. {
  4400. case rm_sequence:
  4401. for (i = 0; i < REGEXP_SEQUENCE (regexp)->regexps_num; i++)
  4402. REGEXP_SEQUENCE (regexp)->regexps [i]
  4403. = regexp_transform_func (REGEXP_SEQUENCE (regexp)->regexps [i],
  4404. func);
  4405. break;
  4406. case rm_allof:
  4407. for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
  4408. REGEXP_ALLOF (regexp)->regexps [i]
  4409. = regexp_transform_func (REGEXP_ALLOF (regexp)->regexps [i], func);
  4410. break;
  4411. case rm_oneof:
  4412. for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
  4413. REGEXP_ONEOF (regexp)->regexps [i]
  4414. = regexp_transform_func (REGEXP_ONEOF (regexp)->regexps [i], func);
  4415. break;
  4416. case rm_repeat:
  4417. REGEXP_REPEAT (regexp)->regexp
  4418. = regexp_transform_func (REGEXP_REPEAT (regexp)->regexp, func);
  4419. break;
  4420. case rm_nothing:
  4421. case rm_unit:
  4422. break;
  4423. default:
  4424. gcc_unreachable ();
  4425. }
  4426. return (*func) (regexp);
  4427. }
  4428. /* The function applies all transformations for IR representation of
  4429. reservation REGEXP. */
  4430. static regexp_t
  4431. transform_regexp (regexp_t regexp)
  4432. {
  4433. regexp = regexp_transform_func (regexp, transform_1);
  4434. do
  4435. {
  4436. regexp_transformed_p = 0;
  4437. regexp = regexp_transform_func (regexp, transform_2);
  4438. regexp = regexp_transform_func (regexp, transform_3);
  4439. }
  4440. while (regexp_transformed_p);
  4441. return regexp;
  4442. }
  4443. /* The function applies all transformations for reservations of all
  4444. insn declarations. */
  4445. static void
  4446. transform_insn_regexps (void)
  4447. {
  4448. decl_t decl;
  4449. int i;
  4450. transform_time = create_ticker ();
  4451. add_advance_cycle_insn_decl ();
  4452. if (collapse_flag)
  4453. add_collapse_ndfa_insn_decl ();
  4454. if (progress_flag)
  4455. fprintf (stderr, "Reservation transformation...");
  4456. for (i = 0; i < description->normal_decls_num; i++)
  4457. {
  4458. decl = description->decls [i];
  4459. if (decl->mode == dm_insn_reserv)
  4460. DECL_INSN_RESERV (decl)->transformed_regexp
  4461. = transform_regexp (copy_insn_regexp
  4462. (DECL_INSN_RESERV (decl)->regexp));
  4463. }
  4464. if (progress_flag)
  4465. fprintf (stderr, "done\n");
  4466. ticker_off (&transform_time);
  4467. }
  4468. /* The following variable value is TRUE if the first annotated message
  4469. about units to automata distribution has been output. */
  4470. static int annotation_message_reported_p;
  4471. /* The vector contains all decls which are automata. */
  4472. static vec<decl_t> automaton_decls;
  4473. /* The following structure describes usage of a unit in a reservation. */
  4474. struct unit_usage
  4475. {
  4476. unit_decl_t unit_decl;
  4477. /* The following forms a list of units used on the same cycle in the
  4478. same alternative. The list is ordered by the correspdoning unit
  4479. declarations and there is no unit declaration duplication in the
  4480. list. */
  4481. struct unit_usage *next;
  4482. };
  4483. typedef struct unit_usage *unit_usage_t;
  4484. /* Obstack for unit_usage structures. */
  4485. static struct obstack unit_usages;
  4486. /* VLA for representation of array of pointers to unit usage
  4487. structures. There is an element for each combination of
  4488. (alternative number, cycle). Unit usages on given cycle in
  4489. alternative with given number are referred through element with
  4490. index equals to the cycle * number of all alternatives in the
  4491. regexp + the alternative number. */
  4492. static vec<unit_usage_t> cycle_alt_unit_usages;
  4493. /* The following function creates the structure unit_usage for UNIT on
  4494. CYCLE in REGEXP alternative with ALT_NUM. The structure is made
  4495. accessed through cycle_alt_unit_usages. */
  4496. static void
  4497. store_alt_unit_usage (regexp_t regexp, regexp_t unit, int cycle,
  4498. int alt_num)
  4499. {
  4500. size_t length;
  4501. unit_decl_t unit_decl;
  4502. unit_usage_t unit_usage_ptr, curr, prev;
  4503. int index;
  4504. gcc_assert (regexp && regexp->mode == rm_oneof
  4505. && alt_num < REGEXP_ONEOF (regexp)->regexps_num);
  4506. unit_decl = REGEXP_UNIT (unit)->unit_decl;
  4507. length = (cycle + 1) * REGEXP_ONEOF (regexp)->regexps_num;
  4508. while (cycle_alt_unit_usages.length () < length)
  4509. cycle_alt_unit_usages.safe_push (NULL);
  4510. index = cycle * REGEXP_ONEOF (regexp)->regexps_num + alt_num;
  4511. prev = NULL;
  4512. for (curr = cycle_alt_unit_usages[index];
  4513. curr != NULL;
  4514. prev = curr, curr = curr->next)
  4515. if (curr->unit_decl >= unit_decl)
  4516. break;
  4517. if (curr != NULL && curr->unit_decl == unit_decl)
  4518. return;
  4519. obstack_blank (&unit_usages, sizeof (struct unit_usage));
  4520. unit_usage_ptr = (struct unit_usage *) obstack_base (&unit_usages);
  4521. obstack_finish (&unit_usages);
  4522. unit_usage_ptr->unit_decl = unit_decl;
  4523. unit_decl->last_distribution_check_cycle = -1; /* undefined */
  4524. unit_usage_ptr->next = curr;
  4525. if (prev == NULL)
  4526. cycle_alt_unit_usages[index] = unit_usage_ptr;
  4527. else
  4528. prev->next = unit_usage_ptr;
  4529. }
  4530. /* Return true if unit UNIT_DECL is present on the LIST. */
  4531. static bool
  4532. unit_present_on_list_p (unit_usage_t list, unit_decl_t unit_decl)
  4533. {
  4534. while (list != NULL)
  4535. {
  4536. if (list->unit_decl == unit_decl)
  4537. return true;
  4538. list = list->next;
  4539. }
  4540. return false;
  4541. }
  4542. /* The function returns true if reservations of alternatives ALT1 and
  4543. ALT2 are equal after excluding reservations of units of
  4544. EXCLUDED_AUTOMATON_DECL. */
  4545. static bool
  4546. equal_alternatives_p (int alt1, int alt2, int n_alts,
  4547. struct automaton_decl *excluded_automaton_decl)
  4548. {
  4549. int i;
  4550. unit_usage_t list1, list2;
  4551. for (i = 0;
  4552. i < (int) cycle_alt_unit_usages.length ();
  4553. i += n_alts)
  4554. {
  4555. for (list1 = cycle_alt_unit_usages[i + alt1],
  4556. list2 = cycle_alt_unit_usages[i + alt2];;
  4557. list1 = list1->next, list2 = list2->next)
  4558. {
  4559. while (list1 != NULL
  4560. && list1->unit_decl->automaton_decl == excluded_automaton_decl)
  4561. list1 = list1->next;
  4562. while (list2 != NULL
  4563. && list2->unit_decl->automaton_decl == excluded_automaton_decl)
  4564. list2 = list2->next;
  4565. if (list1 == NULL || list2 == NULL)
  4566. {
  4567. if (list1 != list2)
  4568. return false;
  4569. else
  4570. break;
  4571. }
  4572. if (list1->unit_decl != list2->unit_decl)
  4573. return false;
  4574. }
  4575. }
  4576. return true;
  4577. }
  4578. /* The function processes given REGEXP to find units with the wrong
  4579. distribution. */
  4580. static void
  4581. check_regexp_units_distribution (const char *insn_reserv_name,
  4582. regexp_t regexp)
  4583. {
  4584. int i, j, k, cycle, start, n_alts, alt, alt2;
  4585. bool annotation_reservation_message_reported_p;
  4586. regexp_t seq, allof, unit;
  4587. struct unit_usage *unit_usage_ptr;
  4588. if (regexp == NULL || regexp->mode != rm_oneof)
  4589. return;
  4590. /* Store all unit usages in the regexp: */
  4591. obstack_init (&unit_usages);
  4592. cycle_alt_unit_usages.create (10);
  4593. for (i = REGEXP_ONEOF (regexp)->regexps_num - 1; i >= 0; i--)
  4594. {
  4595. seq = REGEXP_ONEOF (regexp)->regexps [i];
  4596. switch (seq->mode)
  4597. {
  4598. case rm_sequence:
  4599. for (j = 0; j < REGEXP_SEQUENCE (seq)->regexps_num; j++)
  4600. {
  4601. allof = REGEXP_SEQUENCE (seq)->regexps [j];
  4602. switch (allof->mode)
  4603. {
  4604. case rm_allof:
  4605. for (k = 0; k < REGEXP_ALLOF (allof)->regexps_num; k++)
  4606. {
  4607. unit = REGEXP_ALLOF (allof)->regexps [k];
  4608. if (unit->mode == rm_unit)
  4609. store_alt_unit_usage (regexp, unit, j, i);
  4610. else
  4611. gcc_assert (unit->mode == rm_nothing);
  4612. }
  4613. break;
  4614. case rm_unit:
  4615. store_alt_unit_usage (regexp, allof, j, i);
  4616. break;
  4617. case rm_nothing:
  4618. break;
  4619. default:
  4620. gcc_unreachable ();
  4621. }
  4622. }
  4623. break;
  4624. case rm_allof:
  4625. for (k = 0; k < REGEXP_ALLOF (seq)->regexps_num; k++)
  4626. {
  4627. unit = REGEXP_ALLOF (seq)->regexps [k];
  4628. switch (unit->mode)
  4629. {
  4630. case rm_unit:
  4631. store_alt_unit_usage (regexp, unit, 0, i);
  4632. break;
  4633. case rm_nothing:
  4634. break;
  4635. default:
  4636. gcc_unreachable ();
  4637. }
  4638. }
  4639. break;
  4640. case rm_unit:
  4641. store_alt_unit_usage (regexp, seq, 0, i);
  4642. break;
  4643. case rm_nothing:
  4644. break;
  4645. default:
  4646. gcc_unreachable ();
  4647. }
  4648. }
  4649. /* Check distribution: */
  4650. for (i = 0; i < (int) cycle_alt_unit_usages.length (); i++)
  4651. for (unit_usage_ptr = cycle_alt_unit_usages[i];
  4652. unit_usage_ptr != NULL;
  4653. unit_usage_ptr = unit_usage_ptr->next)
  4654. unit_usage_ptr->unit_decl->last_distribution_check_cycle = -1;
  4655. n_alts = REGEXP_ONEOF (regexp)->regexps_num;
  4656. auto_vec<int> marked (n_alts);
  4657. for (i = 0; i < n_alts; i++)
  4658. marked.safe_push (0);
  4659. annotation_reservation_message_reported_p = false;
  4660. for (i = 0; i < (int) cycle_alt_unit_usages.length (); i++)
  4661. {
  4662. cycle = i / n_alts;
  4663. start = cycle * n_alts;
  4664. for (unit_usage_ptr = cycle_alt_unit_usages[i];
  4665. unit_usage_ptr != NULL;
  4666. unit_usage_ptr = unit_usage_ptr->next)
  4667. {
  4668. if (unit_usage_ptr->unit_decl->last_distribution_check_cycle == cycle)
  4669. continue;
  4670. unit_usage_ptr->unit_decl->last_distribution_check_cycle = cycle;
  4671. for (alt = 0; alt < n_alts; alt++)
  4672. if (! unit_present_on_list_p (cycle_alt_unit_usages[start + alt],
  4673. unit_usage_ptr->unit_decl))
  4674. break;
  4675. if (alt >= n_alts)
  4676. continue;
  4677. memset (marked.address (), 0, n_alts * sizeof (int));
  4678. for (alt = 0; alt < n_alts; alt++)
  4679. {
  4680. if (! unit_present_on_list_p (cycle_alt_unit_usages[start + alt],
  4681. unit_usage_ptr->unit_decl))
  4682. continue;
  4683. for (j = 0;
  4684. j < (int) cycle_alt_unit_usages.length ();
  4685. j++)
  4686. {
  4687. alt2 = j % n_alts;
  4688. if (! unit_present_on_list_p
  4689. (cycle_alt_unit_usages[start + alt2],
  4690. unit_usage_ptr->unit_decl)
  4691. && equal_alternatives_p (alt, alt2, n_alts,
  4692. unit_usage_ptr
  4693. ->unit_decl->automaton_decl))
  4694. {
  4695. marked[alt] = 1;
  4696. marked[alt2] = 1;
  4697. }
  4698. }
  4699. }
  4700. for (alt = 0; alt < n_alts && marked[alt]; alt++)
  4701. ;
  4702. if (alt < n_alts && 0)
  4703. {
  4704. if (! annotation_message_reported_p)
  4705. {
  4706. fprintf (stderr, "\n");
  4707. error ("The following units do not satisfy units-automata distribution rule");
  4708. error ("(Unit presence on one alt and its absence on other alt\n");
  4709. error (" result in different other automata reservations)");
  4710. annotation_message_reported_p = TRUE;
  4711. }
  4712. if (! annotation_reservation_message_reported_p)
  4713. {
  4714. error ("Reserv %s:", insn_reserv_name);
  4715. annotation_reservation_message_reported_p = true;
  4716. }
  4717. error (" Unit %s, cycle %d, alt %d, another alt %d",
  4718. unit_usage_ptr->unit_decl->name, cycle, i % n_alts, alt);
  4719. }
  4720. }
  4721. }
  4722. cycle_alt_unit_usages.release ();
  4723. obstack_free (&unit_usages, NULL);
  4724. }
  4725. /* The function finds units which violates units to automata
  4726. distribution rule. If the units exist, report about them. */
  4727. static void
  4728. check_unit_distributions_to_automata (void)
  4729. {
  4730. decl_t decl;
  4731. int i;
  4732. if (progress_flag)
  4733. fprintf (stderr, "Check unit distributions to automata...");
  4734. automaton_decls.create (0);
  4735. for (i = 0; i < description->decls_num; i++)
  4736. {
  4737. decl = description->decls [i];
  4738. if (decl->mode == dm_automaton)
  4739. automaton_decls.safe_push (decl);
  4740. }
  4741. if (automaton_decls.length () > 1)
  4742. {
  4743. annotation_message_reported_p = FALSE;
  4744. for (i = 0; i < description->decls_num; i++)
  4745. {
  4746. decl = description->decls [i];
  4747. if (decl->mode == dm_insn_reserv)
  4748. check_regexp_units_distribution
  4749. (DECL_INSN_RESERV (decl)->name,
  4750. DECL_INSN_RESERV (decl)->transformed_regexp);
  4751. }
  4752. }
  4753. automaton_decls.release ();
  4754. if (progress_flag)
  4755. fprintf (stderr, "done\n");
  4756. }
  4757. /* The page contains code for building alt_states (see comments for
  4758. IR) describing all possible insns reservations of an automaton. */
  4759. /* Current state being formed for which the current alt_state
  4760. refers. */
  4761. static state_t state_being_formed;
  4762. /* Current alt_state being formed. */
  4763. static alt_state_t alt_state_being_formed;
  4764. /* This recursive function processes `,' and units in reservation
  4765. REGEXP for forming alt_states of AUTOMATON. It is believed that
  4766. CURR_CYCLE is start cycle of all reservation REGEXP. */
  4767. static int
  4768. process_seq_for_forming_states (regexp_t regexp, automaton_t automaton,
  4769. int curr_cycle)
  4770. {
  4771. int i;
  4772. if (regexp == NULL)
  4773. return curr_cycle;
  4774. switch (regexp->mode)
  4775. {
  4776. case rm_unit:
  4777. if (REGEXP_UNIT (regexp)->unit_decl->corresponding_automaton_num
  4778. == automaton->automaton_order_num)
  4779. set_state_reserv (state_being_formed, curr_cycle,
  4780. REGEXP_UNIT (regexp)->unit_decl->unit_num);
  4781. return curr_cycle;
  4782. case rm_sequence:
  4783. for (i = 0; i < REGEXP_SEQUENCE (regexp)->regexps_num; i++)
  4784. curr_cycle
  4785. = process_seq_for_forming_states
  4786. (REGEXP_SEQUENCE (regexp)->regexps [i], automaton, curr_cycle) + 1;
  4787. return curr_cycle;
  4788. case rm_allof:
  4789. {
  4790. int finish_cycle = 0;
  4791. int cycle;
  4792. for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
  4793. {
  4794. cycle = process_seq_for_forming_states (REGEXP_ALLOF (regexp)
  4795. ->regexps [i],
  4796. automaton, curr_cycle);
  4797. if (finish_cycle < cycle)
  4798. finish_cycle = cycle;
  4799. }
  4800. return finish_cycle;
  4801. }
  4802. case rm_nothing:
  4803. return curr_cycle;
  4804. default:
  4805. gcc_unreachable ();
  4806. }
  4807. }
  4808. /* This recursive function finishes forming ALT_STATE of AUTOMATON and
  4809. inserts alt_state into the table. */
  4810. static void
  4811. finish_forming_alt_state (alt_state_t alt_state,
  4812. automaton_t automaton ATTRIBUTE_UNUSED)
  4813. {
  4814. state_t state_in_table;
  4815. state_t corresponding_state;
  4816. corresponding_state = alt_state->state;
  4817. state_in_table = insert_state (corresponding_state);
  4818. if (state_in_table != corresponding_state)
  4819. {
  4820. free_state (corresponding_state);
  4821. alt_state->state = state_in_table;
  4822. }
  4823. }
  4824. /* The following variable value is current automaton insn for whose
  4825. reservation the alt states are created. */
  4826. static ainsn_t curr_ainsn;
  4827. /* This recursive function processes `|' in reservation REGEXP for
  4828. forming alt_states of AUTOMATON. List of the alt states should
  4829. have the same order as in the description. */
  4830. static void
  4831. process_alts_for_forming_states (regexp_t regexp, automaton_t automaton,
  4832. int inside_oneof_p)
  4833. {
  4834. int i;
  4835. if (regexp->mode != rm_oneof)
  4836. {
  4837. alt_state_being_formed = get_free_alt_state ();
  4838. state_being_formed = get_free_state (1, automaton);
  4839. alt_state_being_formed->state = state_being_formed;
  4840. /* We inserts in reverse order but we process alternatives also
  4841. in reverse order. So we have the same order of alternative
  4842. as in the description. */
  4843. alt_state_being_formed->next_alt_state = curr_ainsn->alt_states;
  4844. curr_ainsn->alt_states = alt_state_being_formed;
  4845. (void) process_seq_for_forming_states (regexp, automaton, 0);
  4846. finish_forming_alt_state (alt_state_being_formed, automaton);
  4847. }
  4848. else
  4849. {
  4850. gcc_assert (!inside_oneof_p);
  4851. /* We processes it in reverse order to get list with the same
  4852. order as in the description. See also the previous
  4853. commentary. */
  4854. for (i = REGEXP_ONEOF (regexp)->regexps_num - 1; i >= 0; i--)
  4855. process_alts_for_forming_states (REGEXP_ONEOF (regexp)->regexps [i],
  4856. automaton, 1);
  4857. }
  4858. }
  4859. /* Create nodes alt_state for all AUTOMATON insns. */
  4860. static void
  4861. create_alt_states (automaton_t automaton)
  4862. {
  4863. struct insn_reserv_decl *reserv_decl;
  4864. for (curr_ainsn = automaton->ainsn_list;
  4865. curr_ainsn != NULL;
  4866. curr_ainsn = curr_ainsn->next_ainsn)
  4867. {
  4868. reserv_decl = curr_ainsn->insn_reserv_decl;
  4869. if (!special_decl_p (reserv_decl))
  4870. {
  4871. curr_ainsn->alt_states = NULL;
  4872. process_alts_for_forming_states (reserv_decl->transformed_regexp,
  4873. automaton, 0);
  4874. curr_ainsn->sorted_alt_states
  4875. = uniq_sort_alt_states (curr_ainsn->alt_states);
  4876. }
  4877. }
  4878. }
  4879. /* The page contains major code for building DFA(s) for fast pipeline
  4880. hazards recognition. */
  4881. /* The function forms list of ainsns of AUTOMATON with the same
  4882. reservation. */
  4883. static void
  4884. form_ainsn_with_same_reservs (automaton_t automaton)
  4885. {
  4886. ainsn_t curr_ainsn;
  4887. size_t i;
  4888. auto_vec<ainsn_t, 150> last_insns;
  4889. for (curr_ainsn = automaton->ainsn_list;
  4890. curr_ainsn != NULL;
  4891. curr_ainsn = curr_ainsn->next_ainsn)
  4892. if (special_decl_p (curr_ainsn->insn_reserv_decl))
  4893. {
  4894. curr_ainsn->next_same_reservs_insn = NULL;
  4895. curr_ainsn->first_insn_with_same_reservs = 1;
  4896. }
  4897. else
  4898. {
  4899. for (i = 0; i < last_insns.length (); i++)
  4900. if (alt_states_eq
  4901. (curr_ainsn->sorted_alt_states,
  4902. last_insns[i]->sorted_alt_states))
  4903. break;
  4904. curr_ainsn->next_same_reservs_insn = NULL;
  4905. if (i < last_insns.length ())
  4906. {
  4907. curr_ainsn->first_insn_with_same_reservs = 0;
  4908. last_insns[i]->next_same_reservs_insn = curr_ainsn;
  4909. last_insns[i] = curr_ainsn;
  4910. }
  4911. else
  4912. {
  4913. last_insns.safe_push (curr_ainsn);
  4914. curr_ainsn->first_insn_with_same_reservs = 1;
  4915. }
  4916. }
  4917. }
  4918. /* Forming unit reservations which can affect creating the automaton
  4919. states achieved from a given state. It permits to build smaller
  4920. automata in many cases. We would have the same automata after
  4921. the minimization without such optimization, but the automaton
  4922. right after the building could be huge. So in other words, usage
  4923. of reservs_matter means some minimization during building the
  4924. automaton. */
  4925. static reserv_sets_t
  4926. form_reservs_matter (automaton_t automaton)
  4927. {
  4928. int cycle, unit;
  4929. reserv_sets_t reservs_matter = alloc_empty_reserv_sets ();
  4930. for (cycle = 0; cycle < max_cycles_num; cycle++)
  4931. for (unit = 0; unit < description->units_num; unit++)
  4932. if (units_array [unit]->automaton_decl
  4933. == automaton->corresponding_automaton_decl
  4934. && (cycle >= units_array [unit]->min_occ_cycle_num
  4935. /* We can not remove queried unit from reservations. */
  4936. || units_array [unit]->query_p
  4937. /* We can not remove units which are used
  4938. `exclusion_set', `presence_set',
  4939. `final_presence_set', `absence_set', and
  4940. `final_absence_set'. */
  4941. || units_array [unit]->in_set_p))
  4942. set_unit_reserv (reservs_matter, cycle, unit);
  4943. return reservs_matter;
  4944. }
  4945. /* The following function creates all states of nondeterministic AUTOMATON. */
  4946. static void
  4947. make_automaton (automaton_t automaton)
  4948. {
  4949. ainsn_t ainsn;
  4950. struct insn_reserv_decl *insn_reserv_decl;
  4951. alt_state_t alt_state;
  4952. state_t state;
  4953. state_t start_state;
  4954. state_t state2;
  4955. auto_vec<state_t, 150> state_stack;
  4956. int states_n;
  4957. reserv_sets_t reservs_matter = form_reservs_matter (automaton);
  4958. /* Create the start state (empty state). */
  4959. start_state = insert_state (get_free_state (1, automaton));
  4960. automaton->start_state = start_state;
  4961. start_state->it_was_placed_in_stack_for_NDFA_forming = 1;
  4962. state_stack.safe_push (start_state);
  4963. states_n = 1;
  4964. while (state_stack.length () != 0)
  4965. {
  4966. state = state_stack.pop ();
  4967. for (ainsn = automaton->ainsn_list;
  4968. ainsn != NULL;
  4969. ainsn = ainsn->next_ainsn)
  4970. if (ainsn->first_insn_with_same_reservs)
  4971. {
  4972. insn_reserv_decl = ainsn->insn_reserv_decl;
  4973. if (!special_decl_p (insn_reserv_decl))
  4974. {
  4975. /* We process alt_states in the same order as they are
  4976. present in the description. */
  4977. for (alt_state = ainsn->alt_states;
  4978. alt_state != NULL;
  4979. alt_state = alt_state->next_alt_state)
  4980. {
  4981. state2 = alt_state->state;
  4982. if (!intersected_state_reservs_p (state, state2))
  4983. {
  4984. state2 = states_union (state, state2, reservs_matter);
  4985. if (!state2->it_was_placed_in_stack_for_NDFA_forming)
  4986. {
  4987. state2->it_was_placed_in_stack_for_NDFA_forming
  4988. = 1;
  4989. state_stack.safe_push (state2);
  4990. states_n++;
  4991. if (progress_flag && states_n % 100 == 0)
  4992. fprintf (stderr, ".");
  4993. }
  4994. add_arc (state, state2, ainsn);
  4995. if (!ndfa_flag)
  4996. break;
  4997. }
  4998. }
  4999. }
  5000. }
  5001. /* Add transition to advance cycle. */
  5002. state2 = state_shift (state, reservs_matter);
  5003. if (!state2->it_was_placed_in_stack_for_NDFA_forming)
  5004. {
  5005. state2->it_was_placed_in_stack_for_NDFA_forming = 1;
  5006. state_stack.safe_push (state2);
  5007. states_n++;
  5008. if (progress_flag && states_n % 100 == 0)
  5009. fprintf (stderr, ".");
  5010. }
  5011. add_arc (state, state2, automaton->advance_ainsn);
  5012. }
  5013. }
  5014. /* Form lists of all arcs of STATE marked by the same ainsn. */
  5015. static void
  5016. form_arcs_marked_by_insn (state_t state)
  5017. {
  5018. decl_t decl;
  5019. arc_t arc;
  5020. int i;
  5021. for (i = 0; i < description->decls_num; i++)
  5022. {
  5023. decl = description->decls [i];
  5024. if (decl->mode == dm_insn_reserv)
  5025. DECL_INSN_RESERV (decl)->arcs_marked_by_insn = NULL;
  5026. }
  5027. for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
  5028. {
  5029. gcc_assert (arc->insn);
  5030. arc->next_arc_marked_by_insn
  5031. = arc->insn->insn_reserv_decl->arcs_marked_by_insn;
  5032. arc->insn->insn_reserv_decl->arcs_marked_by_insn = arc;
  5033. }
  5034. }
  5035. /* The function creates composed state (see comments for IR) from
  5036. ORIGINAL_STATE and list of arcs ARCS_MARKED_BY_INSN marked by the
  5037. same insn. If the composed state is not in STATE_STACK yet, it is
  5038. pushed into STATE_STACK. */
  5039. static int
  5040. create_composed_state (state_t original_state, arc_t arcs_marked_by_insn,
  5041. vec<state_t> *state_stack)
  5042. {
  5043. state_t state;
  5044. alt_state_t alt_state, curr_alt_state;
  5045. alt_state_t new_alt_state;
  5046. arc_t curr_arc;
  5047. arc_t next_arc;
  5048. state_t state_in_table;
  5049. state_t temp_state;
  5050. alt_state_t canonical_alt_states_list;
  5051. int alts_number;
  5052. int new_state_p = 0;
  5053. if (arcs_marked_by_insn == NULL)
  5054. return new_state_p;
  5055. if (arcs_marked_by_insn->next_arc_marked_by_insn == NULL)
  5056. state = arcs_marked_by_insn->to_state;
  5057. else
  5058. {
  5059. gcc_assert (ndfa_flag);
  5060. /* Create composed state. */
  5061. state = get_free_state (0, arcs_marked_by_insn->to_state->automaton);
  5062. curr_alt_state = NULL;
  5063. for (curr_arc = arcs_marked_by_insn;
  5064. curr_arc != NULL;
  5065. curr_arc = curr_arc->next_arc_marked_by_insn)
  5066. if (curr_arc->to_state->component_states == NULL)
  5067. {
  5068. new_alt_state = get_free_alt_state ();
  5069. new_alt_state->next_alt_state = curr_alt_state;
  5070. new_alt_state->state = curr_arc->to_state;
  5071. curr_alt_state = new_alt_state;
  5072. }
  5073. else
  5074. for (alt_state = curr_arc->to_state->component_states;
  5075. alt_state != NULL;
  5076. alt_state = alt_state->next_sorted_alt_state)
  5077. {
  5078. new_alt_state = get_free_alt_state ();
  5079. new_alt_state->next_alt_state = curr_alt_state;
  5080. new_alt_state->state = alt_state->state;
  5081. gcc_assert (!alt_state->state->component_states);
  5082. curr_alt_state = new_alt_state;
  5083. }
  5084. /* There are not identical sets in the alt state list. */
  5085. canonical_alt_states_list = uniq_sort_alt_states (curr_alt_state);
  5086. if (canonical_alt_states_list->next_sorted_alt_state == NULL)
  5087. {
  5088. temp_state = state;
  5089. state = canonical_alt_states_list->state;
  5090. free_state (temp_state);
  5091. }
  5092. else
  5093. {
  5094. state->component_states = canonical_alt_states_list;
  5095. state_in_table = insert_state (state);
  5096. if (state_in_table != state)
  5097. {
  5098. gcc_assert
  5099. (state_in_table->it_was_placed_in_stack_for_DFA_forming);
  5100. free_state (state);
  5101. state = state_in_table;
  5102. }
  5103. else
  5104. {
  5105. gcc_assert (!state->it_was_placed_in_stack_for_DFA_forming);
  5106. new_state_p = 1;
  5107. for (curr_alt_state = state->component_states;
  5108. curr_alt_state != NULL;
  5109. curr_alt_state = curr_alt_state->next_sorted_alt_state)
  5110. for (curr_arc = first_out_arc (curr_alt_state->state);
  5111. curr_arc != NULL;
  5112. curr_arc = next_out_arc (curr_arc))
  5113. if (!collapse_flag
  5114. /* When producing collapse-NDFA transitions, we
  5115. only add advance-cycle transitions to the
  5116. collapsed states. */
  5117. || (curr_arc->insn->insn_reserv_decl
  5118. != DECL_INSN_RESERV (advance_cycle_insn_decl)))
  5119. add_arc (state, curr_arc->to_state, curr_arc->insn);
  5120. }
  5121. arcs_marked_by_insn->to_state = state;
  5122. for (alts_number = 0,
  5123. curr_arc = arcs_marked_by_insn->next_arc_marked_by_insn;
  5124. curr_arc != NULL;
  5125. curr_arc = next_arc)
  5126. {
  5127. next_arc = curr_arc->next_arc_marked_by_insn;
  5128. remove_arc (original_state, curr_arc);
  5129. alts_number++;
  5130. }
  5131. }
  5132. }
  5133. if (!state->it_was_placed_in_stack_for_DFA_forming)
  5134. {
  5135. state->it_was_placed_in_stack_for_DFA_forming = 1;
  5136. state_stack->safe_push (state);
  5137. }
  5138. return new_state_p;
  5139. }
  5140. /* The function transforms nondeterministic AUTOMATON into
  5141. deterministic. */
  5142. static void
  5143. NDFA_to_DFA (automaton_t automaton)
  5144. {
  5145. state_t start_state;
  5146. state_t state;
  5147. decl_t decl;
  5148. auto_vec<state_t> state_stack;
  5149. int i;
  5150. int states_n;
  5151. /* Create the start state (empty state). */
  5152. start_state = automaton->start_state;
  5153. start_state->it_was_placed_in_stack_for_DFA_forming = 1;
  5154. state_stack.safe_push (start_state);
  5155. states_n = 1;
  5156. while (state_stack.length () != 0)
  5157. {
  5158. state = state_stack.pop ();
  5159. form_arcs_marked_by_insn (state);
  5160. for (i = 0; i < description->decls_num; i++)
  5161. {
  5162. decl = description->decls [i];
  5163. if (decl->mode == dm_insn_reserv
  5164. && decl != collapse_ndfa_insn_decl
  5165. && create_composed_state
  5166. (state, DECL_INSN_RESERV (decl)->arcs_marked_by_insn,
  5167. &state_stack))
  5168. {
  5169. states_n++;
  5170. if (progress_flag && states_n % 100 == 0)
  5171. fprintf (stderr, ".");
  5172. }
  5173. }
  5174. /* Add a transition to collapse the NDFA. */
  5175. if (collapse_flag)
  5176. {
  5177. if (state->component_states != NULL)
  5178. {
  5179. state_t state2 = state->component_states->state;
  5180. if (!state2->it_was_placed_in_stack_for_DFA_forming)
  5181. {
  5182. state2->it_was_placed_in_stack_for_DFA_forming = 1;
  5183. state_stack.safe_push (state2);
  5184. }
  5185. add_arc (state, state2, automaton->collapse_ainsn);
  5186. }
  5187. else
  5188. add_arc (state, state, automaton->collapse_ainsn);
  5189. }
  5190. }
  5191. }
  5192. /* The following variable value is current number (1, 2, ...) of passing
  5193. graph of states. */
  5194. static int curr_state_graph_pass_num;
  5195. /* This recursive function passes all states achieved from START_STATE
  5196. and applies APPLIED_FUNC to them. */
  5197. static void
  5198. pass_state_graph (state_t start_state, void (*applied_func) (state_t state))
  5199. {
  5200. arc_t arc;
  5201. if (start_state->pass_num == curr_state_graph_pass_num)
  5202. return;
  5203. start_state->pass_num = curr_state_graph_pass_num;
  5204. (*applied_func) (start_state);
  5205. for (arc = first_out_arc (start_state);
  5206. arc != NULL;
  5207. arc = next_out_arc (arc))
  5208. pass_state_graph (arc->to_state, applied_func);
  5209. }
  5210. /* This recursive function passes all states of AUTOMATON and applies
  5211. APPLIED_FUNC to them. */
  5212. static void
  5213. pass_states (automaton_t automaton, void (*applied_func) (state_t state))
  5214. {
  5215. curr_state_graph_pass_num++;
  5216. pass_state_graph (automaton->start_state, applied_func);
  5217. }
  5218. /* The function initializes code for passing of all states. */
  5219. static void
  5220. initiate_pass_states (void)
  5221. {
  5222. curr_state_graph_pass_num = 0;
  5223. }
  5224. /* The following vla is used for storing pointers to all achieved
  5225. states. */
  5226. static vec<state_t> all_achieved_states;
  5227. /* This function is called by function pass_states to add an achieved
  5228. STATE. */
  5229. static void
  5230. add_achieved_state (state_t state)
  5231. {
  5232. all_achieved_states.safe_push (state);
  5233. }
  5234. /* The function sets up equivalence numbers of insns which mark all
  5235. out arcs of STATE by equiv_class_num_1 (if ODD_ITERATION_FLAG has
  5236. nonzero value) or by equiv_class_num_2 of the destination state. */
  5237. static void
  5238. set_out_arc_insns_equiv_num (state_t state, int odd_iteration_flag)
  5239. {
  5240. arc_t arc;
  5241. for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
  5242. {
  5243. gcc_assert (!arc->insn->insn_reserv_decl->equiv_class_num);
  5244. arc->insn->insn_reserv_decl->equiv_class_num
  5245. = (odd_iteration_flag
  5246. ? arc->to_state->equiv_class_num_1
  5247. : arc->to_state->equiv_class_num_2);
  5248. gcc_assert (arc->insn->insn_reserv_decl->equiv_class_num);
  5249. }
  5250. }
  5251. /* The function clears equivalence numbers and alt_states in all insns
  5252. which mark all out arcs of STATE. */
  5253. static void
  5254. clear_arc_insns_equiv_num (state_t state)
  5255. {
  5256. arc_t arc;
  5257. for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
  5258. arc->insn->insn_reserv_decl->equiv_class_num = 0;
  5259. }
  5260. /* The following function returns TRUE if STATE reserves the unit with
  5261. UNIT_NUM on the first cycle. */
  5262. static int
  5263. first_cycle_unit_presence (state_t state, int unit_num)
  5264. {
  5265. alt_state_t alt_state;
  5266. if (state->component_states == NULL)
  5267. return test_unit_reserv (state->reservs, 0, unit_num);
  5268. else
  5269. {
  5270. for (alt_state = state->component_states;
  5271. alt_state != NULL;
  5272. alt_state = alt_state->next_sorted_alt_state)
  5273. if (test_unit_reserv (alt_state->state->reservs, 0, unit_num))
  5274. return true;
  5275. }
  5276. return false;
  5277. }
  5278. /* This fills in the presence_signature[] member of STATE. */
  5279. static void
  5280. cache_presence (state_t state)
  5281. {
  5282. int i, num = 0;
  5283. unsigned int sz;
  5284. sz = (description->query_units_num + sizeof (int) * CHAR_BIT - 1)
  5285. / (sizeof (int) * CHAR_BIT);
  5286. state->presence_signature = XCREATENODEVEC (unsigned int, sz);
  5287. for (i = 0; i < description->units_num; i++)
  5288. if (units_array [i]->query_p)
  5289. {
  5290. int presence1_p = first_cycle_unit_presence (state, i);
  5291. state->presence_signature[num / (sizeof (int) * CHAR_BIT)]
  5292. |= (!!presence1_p) << (num % (sizeof (int) * CHAR_BIT));
  5293. num++;
  5294. }
  5295. }
  5296. /* The function returns nonzero value if STATE is not equivalent to
  5297. ANOTHER_STATE from the same current partition on equivalence
  5298. classes. Another state has ANOTHER_STATE_OUT_ARCS_NUM number of
  5299. output arcs. Iteration of making equivalence partition is defined
  5300. by ODD_ITERATION_FLAG. */
  5301. static int
  5302. state_is_differed (state_t state, state_t another_state,
  5303. int odd_iteration_flag)
  5304. {
  5305. arc_t arc;
  5306. unsigned int sz, si;
  5307. gcc_assert (state->num_out_arcs == another_state->num_out_arcs);
  5308. sz = (description->query_units_num + sizeof (int) * CHAR_BIT - 1)
  5309. / (sizeof (int) * CHAR_BIT);
  5310. for (si = 0; si < sz; si++)
  5311. gcc_assert (state->presence_signature[si]
  5312. == another_state->presence_signature[si]);
  5313. for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
  5314. {
  5315. if ((odd_iteration_flag
  5316. ? arc->to_state->equiv_class_num_1
  5317. : arc->to_state->equiv_class_num_2)
  5318. != arc->insn->insn_reserv_decl->equiv_class_num)
  5319. return 1;
  5320. }
  5321. return 0;
  5322. }
  5323. /* Compares two states pointed to by STATE_PTR_1 and STATE_PTR_2
  5324. and return -1, 0 or 1. This function can be used as predicate for
  5325. qsort(). It requires the member presence_signature[] of both
  5326. states be filled. */
  5327. static int
  5328. compare_states_for_equiv (const void *state_ptr_1,
  5329. const void *state_ptr_2)
  5330. {
  5331. const_state_t const s1 = *(const_state_t const*)state_ptr_1;
  5332. const_state_t const s2 = *(const_state_t const*)state_ptr_2;
  5333. unsigned int sz, si;
  5334. if (s1->num_out_arcs < s2->num_out_arcs)
  5335. return -1;
  5336. else if (s1->num_out_arcs > s2->num_out_arcs)
  5337. return 1;
  5338. sz = (description->query_units_num + sizeof (int) * CHAR_BIT - 1)
  5339. / (sizeof (int) * CHAR_BIT);
  5340. for (si = 0; si < sz; si++)
  5341. if (s1->presence_signature[si] < s2->presence_signature[si])
  5342. return -1;
  5343. else if (s1->presence_signature[si] > s2->presence_signature[si])
  5344. return 1;
  5345. return 0;
  5346. }
  5347. /* The function makes initial partition of STATES on equivalent
  5348. classes and saves it into CLASSES. This function requires the input
  5349. to be sorted via compare_states_for_equiv(). */
  5350. static int
  5351. init_equiv_class (vec<state_t> states, vec<state_t> *classes)
  5352. {
  5353. size_t i;
  5354. state_t prev = 0;
  5355. int class_num = 1;
  5356. classes->create (150);
  5357. for (i = 0; i < states.length (); i++)
  5358. {
  5359. state_t state = states[i];
  5360. if (prev)
  5361. {
  5362. if (compare_states_for_equiv (&prev, &state) != 0)
  5363. {
  5364. classes->safe_push (prev);
  5365. class_num++;
  5366. prev = NULL;
  5367. }
  5368. }
  5369. state->equiv_class_num_1 = class_num;
  5370. state->next_equiv_class_state = prev;
  5371. prev = state;
  5372. }
  5373. if (prev)
  5374. classes->safe_push (prev);
  5375. return class_num;
  5376. }
  5377. /* The function copies pointers to equivalent states from vla FROM
  5378. into vla TO. */
  5379. static void
  5380. copy_equiv_class (vec<state_t> *to, vec<state_t> from)
  5381. {
  5382. to->release ();
  5383. *to = from.copy ();
  5384. }
  5385. /* The function processes equivalence class given by its first state,
  5386. FIRST_STATE, on odd iteration if ODD_ITERATION_FLAG. If there
  5387. are not equivalent states, the function partitions the class
  5388. removing nonequivalent states and placing them in
  5389. *NEXT_ITERATION_CLASSES, increments *NEW_EQUIV_CLASS_NUM_PTR ans
  5390. assigns it to the state equivalence number. If the class has been
  5391. partitioned, the function returns nonzero value. */
  5392. static int
  5393. partition_equiv_class (state_t first_state, int odd_iteration_flag,
  5394. vec<state_t> *next_iteration_classes,
  5395. int *new_equiv_class_num_ptr)
  5396. {
  5397. state_t new_equiv_class;
  5398. int partition_p;
  5399. state_t curr_state;
  5400. state_t prev_state;
  5401. state_t next_state;
  5402. partition_p = 0;
  5403. while (first_state != NULL)
  5404. {
  5405. new_equiv_class = NULL;
  5406. if (first_state->next_equiv_class_state != NULL)
  5407. {
  5408. /* There are more one states in the class equivalence. */
  5409. set_out_arc_insns_equiv_num (first_state, odd_iteration_flag);
  5410. for (prev_state = first_state,
  5411. curr_state = first_state->next_equiv_class_state;
  5412. curr_state != NULL;
  5413. curr_state = next_state)
  5414. {
  5415. next_state = curr_state->next_equiv_class_state;
  5416. if (state_is_differed (curr_state, first_state,
  5417. odd_iteration_flag))
  5418. {
  5419. /* Remove curr state from the class equivalence. */
  5420. prev_state->next_equiv_class_state = next_state;
  5421. /* Add curr state to the new class equivalence. */
  5422. curr_state->next_equiv_class_state = new_equiv_class;
  5423. if (new_equiv_class == NULL)
  5424. (*new_equiv_class_num_ptr)++;
  5425. if (odd_iteration_flag)
  5426. curr_state->equiv_class_num_2 = *new_equiv_class_num_ptr;
  5427. else
  5428. curr_state->equiv_class_num_1 = *new_equiv_class_num_ptr;
  5429. new_equiv_class = curr_state;
  5430. partition_p = 1;
  5431. }
  5432. else
  5433. prev_state = curr_state;
  5434. }
  5435. clear_arc_insns_equiv_num (first_state);
  5436. }
  5437. if (new_equiv_class != NULL)
  5438. next_iteration_classes->safe_push (new_equiv_class);
  5439. first_state = new_equiv_class;
  5440. }
  5441. return partition_p;
  5442. }
  5443. /* The function finds equivalent states of AUTOMATON. */
  5444. static void
  5445. evaluate_equiv_classes (automaton_t automaton, vec<state_t> *equiv_classes)
  5446. {
  5447. int new_equiv_class_num;
  5448. int odd_iteration_flag;
  5449. int finish_flag;
  5450. vec<state_t> next_iteration_classes;
  5451. size_t i;
  5452. all_achieved_states.create (1500);
  5453. pass_states (automaton, add_achieved_state);
  5454. pass_states (automaton, cache_presence);
  5455. all_achieved_states.qsort (compare_states_for_equiv);
  5456. odd_iteration_flag = 0;
  5457. new_equiv_class_num = init_equiv_class (all_achieved_states,
  5458. &next_iteration_classes);
  5459. do
  5460. {
  5461. odd_iteration_flag = !odd_iteration_flag;
  5462. finish_flag = 1;
  5463. copy_equiv_class (equiv_classes, next_iteration_classes);
  5464. /* Transfer equiv numbers for the next iteration. */
  5465. for (i = 0; i < all_achieved_states.length (); i++)
  5466. if (odd_iteration_flag)
  5467. all_achieved_states[i]->equiv_class_num_2
  5468. = all_achieved_states[i]->equiv_class_num_1;
  5469. else
  5470. all_achieved_states[i]->equiv_class_num_1
  5471. = all_achieved_states[i]->equiv_class_num_2;
  5472. for (i = 0; i < equiv_classes->length (); i++)
  5473. if (partition_equiv_class ((*equiv_classes)[i],
  5474. odd_iteration_flag,
  5475. &next_iteration_classes,
  5476. &new_equiv_class_num))
  5477. finish_flag = 0;
  5478. }
  5479. while (!finish_flag);
  5480. next_iteration_classes.release ();
  5481. all_achieved_states.release ();
  5482. }
  5483. /* The function merges equivalent states of AUTOMATON. */
  5484. static void
  5485. merge_states (automaton_t automaton, vec<state_t> equiv_classes)
  5486. {
  5487. state_t curr_state;
  5488. state_t new_state;
  5489. state_t first_class_state;
  5490. alt_state_t alt_states;
  5491. alt_state_t alt_state, new_alt_state;
  5492. arc_t curr_arc;
  5493. arc_t next_arc;
  5494. size_t i;
  5495. /* Create states corresponding to equivalence classes containing two
  5496. or more states. */
  5497. for (i = 0; i < equiv_classes.length (); i++)
  5498. {
  5499. curr_state = equiv_classes[i];
  5500. if (curr_state->next_equiv_class_state != NULL)
  5501. {
  5502. /* There are more one states in the class equivalence. */
  5503. /* Create new compound state. */
  5504. new_state = get_free_state (0, automaton);
  5505. alt_states = NULL;
  5506. first_class_state = curr_state;
  5507. for (curr_state = first_class_state;
  5508. curr_state != NULL;
  5509. curr_state = curr_state->next_equiv_class_state)
  5510. {
  5511. curr_state->equiv_class_state = new_state;
  5512. if (curr_state->component_states == NULL)
  5513. {
  5514. new_alt_state = get_free_alt_state ();
  5515. new_alt_state->state = curr_state;
  5516. new_alt_state->next_alt_state = alt_states;
  5517. alt_states = new_alt_state;
  5518. }
  5519. else
  5520. for (alt_state = curr_state->component_states;
  5521. alt_state != NULL;
  5522. alt_state = alt_state->next_sorted_alt_state)
  5523. {
  5524. new_alt_state = get_free_alt_state ();
  5525. new_alt_state->state = alt_state->state;
  5526. new_alt_state->next_alt_state = alt_states;
  5527. alt_states = new_alt_state;
  5528. }
  5529. }
  5530. /* It is important that alt states were sorted before and
  5531. after merging to have the same querying results. */
  5532. new_state->component_states = uniq_sort_alt_states (alt_states);
  5533. }
  5534. else
  5535. curr_state->equiv_class_state = curr_state;
  5536. }
  5537. for (i = 0; i < equiv_classes.length (); i++)
  5538. {
  5539. curr_state = equiv_classes[i];
  5540. if (curr_state->next_equiv_class_state != NULL)
  5541. {
  5542. first_class_state = curr_state;
  5543. /* Create new arcs output from the state corresponding to
  5544. equiv class. */
  5545. for (curr_arc = first_out_arc (first_class_state);
  5546. curr_arc != NULL;
  5547. curr_arc = next_out_arc (curr_arc))
  5548. add_arc (first_class_state->equiv_class_state,
  5549. curr_arc->to_state->equiv_class_state,
  5550. curr_arc->insn);
  5551. /* Delete output arcs from states of given class equivalence. */
  5552. for (curr_state = first_class_state;
  5553. curr_state != NULL;
  5554. curr_state = curr_state->next_equiv_class_state)
  5555. {
  5556. if (automaton->start_state == curr_state)
  5557. automaton->start_state = curr_state->equiv_class_state;
  5558. /* Delete the state and its output arcs. */
  5559. for (curr_arc = first_out_arc (curr_state);
  5560. curr_arc != NULL;
  5561. curr_arc = next_arc)
  5562. {
  5563. next_arc = next_out_arc (curr_arc);
  5564. free_arc (curr_arc);
  5565. }
  5566. }
  5567. }
  5568. else
  5569. {
  5570. /* Change `to_state' of arcs output from the state of given
  5571. equivalence class. */
  5572. for (curr_arc = first_out_arc (curr_state);
  5573. curr_arc != NULL;
  5574. curr_arc = next_out_arc (curr_arc))
  5575. curr_arc->to_state = curr_arc->to_state->equiv_class_state;
  5576. }
  5577. }
  5578. }
  5579. /* The function sets up new_cycle_p for states if there is arc to the
  5580. state marked by advance_cycle_insn_decl. */
  5581. static void
  5582. set_new_cycle_flags (state_t state)
  5583. {
  5584. arc_t arc;
  5585. for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
  5586. if (arc->insn->insn_reserv_decl
  5587. == DECL_INSN_RESERV (advance_cycle_insn_decl))
  5588. arc->to_state->new_cycle_p = 1;
  5589. }
  5590. /* The top level function for minimization of deterministic
  5591. AUTOMATON. */
  5592. static void
  5593. minimize_DFA (automaton_t automaton)
  5594. {
  5595. auto_vec<state_t> equiv_classes;
  5596. evaluate_equiv_classes (automaton, &equiv_classes);
  5597. merge_states (automaton, equiv_classes);
  5598. pass_states (automaton, set_new_cycle_flags);
  5599. }
  5600. /* Values of two variables are counted number of states and arcs in an
  5601. automaton. */
  5602. static int curr_counted_states_num;
  5603. static int curr_counted_arcs_num;
  5604. /* The function is called by function `pass_states' to count states
  5605. and arcs of an automaton. */
  5606. static void
  5607. incr_states_and_arcs_nums (state_t state)
  5608. {
  5609. arc_t arc;
  5610. curr_counted_states_num++;
  5611. for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
  5612. curr_counted_arcs_num++;
  5613. }
  5614. /* The function counts states and arcs of AUTOMATON. */
  5615. static void
  5616. count_states_and_arcs (automaton_t automaton, int *states_num,
  5617. int *arcs_num)
  5618. {
  5619. curr_counted_states_num = 0;
  5620. curr_counted_arcs_num = 0;
  5621. pass_states (automaton, incr_states_and_arcs_nums);
  5622. *states_num = curr_counted_states_num;
  5623. *arcs_num = curr_counted_arcs_num;
  5624. }
  5625. /* The function builds one DFA AUTOMATON for fast pipeline hazards
  5626. recognition after checking and simplifying IR of the
  5627. description. */
  5628. static void
  5629. build_automaton (automaton_t automaton)
  5630. {
  5631. int states_num;
  5632. int arcs_num;
  5633. ticker_on (&NDFA_time);
  5634. if (progress_flag)
  5635. {
  5636. if (automaton->corresponding_automaton_decl == NULL)
  5637. fprintf (stderr, "Create anonymous automaton");
  5638. else
  5639. fprintf (stderr, "Create automaton `%s'",
  5640. automaton->corresponding_automaton_decl->name);
  5641. fprintf (stderr, " (1 dot is 100 new states):");
  5642. }
  5643. make_automaton (automaton);
  5644. if (progress_flag)
  5645. fprintf (stderr, " done\n");
  5646. ticker_off (&NDFA_time);
  5647. count_states_and_arcs (automaton, &states_num, &arcs_num);
  5648. automaton->NDFA_states_num = states_num;
  5649. automaton->NDFA_arcs_num = arcs_num;
  5650. ticker_on (&NDFA_to_DFA_time);
  5651. if (progress_flag)
  5652. {
  5653. if (automaton->corresponding_automaton_decl == NULL)
  5654. fprintf (stderr, "Make anonymous DFA");
  5655. else
  5656. fprintf (stderr, "Make DFA `%s'",
  5657. automaton->corresponding_automaton_decl->name);
  5658. fprintf (stderr, " (1 dot is 100 new states):");
  5659. }
  5660. NDFA_to_DFA (automaton);
  5661. if (progress_flag)
  5662. fprintf (stderr, " done\n");
  5663. ticker_off (&NDFA_to_DFA_time);
  5664. count_states_and_arcs (automaton, &states_num, &arcs_num);
  5665. automaton->DFA_states_num = states_num;
  5666. automaton->DFA_arcs_num = arcs_num;
  5667. if (!no_minimization_flag)
  5668. {
  5669. ticker_on (&minimize_time);
  5670. if (progress_flag)
  5671. {
  5672. if (automaton->corresponding_automaton_decl == NULL)
  5673. fprintf (stderr, "Minimize anonymous DFA...");
  5674. else
  5675. fprintf (stderr, "Minimize DFA `%s'...",
  5676. automaton->corresponding_automaton_decl->name);
  5677. }
  5678. minimize_DFA (automaton);
  5679. if (progress_flag)
  5680. fprintf (stderr, "done\n");
  5681. ticker_off (&minimize_time);
  5682. count_states_and_arcs (automaton, &states_num, &arcs_num);
  5683. automaton->minimal_DFA_states_num = states_num;
  5684. automaton->minimal_DFA_arcs_num = arcs_num;
  5685. }
  5686. }
  5687. /* The page contains code for enumeration of all states of an automaton. */
  5688. /* Variable used for enumeration of all states of an automaton. Its
  5689. value is current number of automaton states. */
  5690. static int curr_state_order_num;
  5691. /* The function is called by function `pass_states' for enumerating
  5692. states. */
  5693. static void
  5694. set_order_state_num (state_t state)
  5695. {
  5696. state->order_state_num = curr_state_order_num;
  5697. curr_state_order_num++;
  5698. }
  5699. /* The function enumerates all states of AUTOMATON. */
  5700. static void
  5701. enumerate_states (automaton_t automaton)
  5702. {
  5703. curr_state_order_num = 0;
  5704. pass_states (automaton, set_order_state_num);
  5705. automaton->achieved_states_num = curr_state_order_num;
  5706. }
  5707. /* The page contains code for finding equivalent automaton insns
  5708. (ainsns). */
  5709. /* The function inserts AINSN into cyclic list
  5710. CYCLIC_EQUIV_CLASS_INSN_LIST of ainsns. */
  5711. static ainsn_t
  5712. insert_ainsn_into_equiv_class (ainsn_t ainsn,
  5713. ainsn_t cyclic_equiv_class_insn_list)
  5714. {
  5715. if (cyclic_equiv_class_insn_list == NULL)
  5716. ainsn->next_equiv_class_insn = ainsn;
  5717. else
  5718. {
  5719. ainsn->next_equiv_class_insn
  5720. = cyclic_equiv_class_insn_list->next_equiv_class_insn;
  5721. cyclic_equiv_class_insn_list->next_equiv_class_insn = ainsn;
  5722. }
  5723. return ainsn;
  5724. }
  5725. /* The function deletes equiv_class_insn into cyclic list of
  5726. equivalent ainsns. */
  5727. static void
  5728. delete_ainsn_from_equiv_class (ainsn_t equiv_class_insn)
  5729. {
  5730. ainsn_t curr_equiv_class_insn;
  5731. ainsn_t prev_equiv_class_insn;
  5732. prev_equiv_class_insn = equiv_class_insn;
  5733. for (curr_equiv_class_insn = equiv_class_insn->next_equiv_class_insn;
  5734. curr_equiv_class_insn != equiv_class_insn;
  5735. curr_equiv_class_insn = curr_equiv_class_insn->next_equiv_class_insn)
  5736. prev_equiv_class_insn = curr_equiv_class_insn;
  5737. if (prev_equiv_class_insn != equiv_class_insn)
  5738. prev_equiv_class_insn->next_equiv_class_insn
  5739. = equiv_class_insn->next_equiv_class_insn;
  5740. }
  5741. /* The function processes AINSN of a state in order to find equivalent
  5742. ainsns. INSN_ARCS_ARRAY is table: code of insn -> out arc of the
  5743. state. */
  5744. static void
  5745. process_insn_equiv_class (ainsn_t ainsn, arc_t *insn_arcs_array)
  5746. {
  5747. ainsn_t next_insn;
  5748. ainsn_t curr_insn;
  5749. ainsn_t cyclic_insn_list;
  5750. arc_t arc;
  5751. gcc_assert (insn_arcs_array [ainsn->insn_reserv_decl->insn_num]);
  5752. curr_insn = ainsn;
  5753. /* New class of ainsns which are not equivalent to given ainsn. */
  5754. cyclic_insn_list = NULL;
  5755. do
  5756. {
  5757. next_insn = curr_insn->next_equiv_class_insn;
  5758. arc = insn_arcs_array [curr_insn->insn_reserv_decl->insn_num];
  5759. if (arc == NULL
  5760. || (insn_arcs_array [ainsn->insn_reserv_decl->insn_num]->to_state
  5761. != arc->to_state))
  5762. {
  5763. delete_ainsn_from_equiv_class (curr_insn);
  5764. cyclic_insn_list = insert_ainsn_into_equiv_class (curr_insn,
  5765. cyclic_insn_list);
  5766. }
  5767. curr_insn = next_insn;
  5768. }
  5769. while (curr_insn != ainsn);
  5770. }
  5771. /* The function processes STATE in order to find equivalent ainsns. */
  5772. static void
  5773. process_state_for_insn_equiv_partition (state_t state)
  5774. {
  5775. arc_t arc;
  5776. arc_t *insn_arcs_array = XCNEWVEC (arc_t, description->insns_num);
  5777. /* Process insns of the arcs. */
  5778. for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
  5779. insn_arcs_array [arc->insn->insn_reserv_decl->insn_num] = arc;
  5780. for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
  5781. process_insn_equiv_class (arc->insn, insn_arcs_array);
  5782. free (insn_arcs_array);
  5783. }
  5784. /* The function searches for equivalent ainsns of AUTOMATON. */
  5785. static void
  5786. set_insn_equiv_classes (automaton_t automaton)
  5787. {
  5788. ainsn_t ainsn;
  5789. ainsn_t first_insn;
  5790. ainsn_t curr_insn;
  5791. ainsn_t cyclic_insn_list;
  5792. ainsn_t insn_with_same_reservs;
  5793. int equiv_classes_num;
  5794. /* All insns are included in one equivalence class. */
  5795. cyclic_insn_list = NULL;
  5796. for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn)
  5797. if (ainsn->first_insn_with_same_reservs)
  5798. cyclic_insn_list = insert_ainsn_into_equiv_class (ainsn,
  5799. cyclic_insn_list);
  5800. /* Process insns in order to make equivalence partition. */
  5801. pass_states (automaton, process_state_for_insn_equiv_partition);
  5802. /* Enumerate equiv classes. */
  5803. for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn)
  5804. /* Set undefined value. */
  5805. ainsn->insn_equiv_class_num = -1;
  5806. equiv_classes_num = 0;
  5807. for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn)
  5808. if (ainsn->insn_equiv_class_num < 0)
  5809. {
  5810. first_insn = ainsn;
  5811. gcc_assert (first_insn->first_insn_with_same_reservs);
  5812. first_insn->first_ainsn_with_given_equivalence_num = 1;
  5813. curr_insn = first_insn;
  5814. do
  5815. {
  5816. for (insn_with_same_reservs = curr_insn;
  5817. insn_with_same_reservs != NULL;
  5818. insn_with_same_reservs
  5819. = insn_with_same_reservs->next_same_reservs_insn)
  5820. insn_with_same_reservs->insn_equiv_class_num = equiv_classes_num;
  5821. curr_insn = curr_insn->next_equiv_class_insn;
  5822. }
  5823. while (curr_insn != first_insn);
  5824. equiv_classes_num++;
  5825. }
  5826. automaton->insn_equiv_classes_num = equiv_classes_num;
  5827. }
  5828. /* This page contains code for creating DFA(s) and calls functions
  5829. building them. */
  5830. /* The following value is used to prevent floating point overflow for
  5831. estimating an automaton bound. The value should be less DBL_MAX on
  5832. the host machine. We use here approximate minimum of maximal
  5833. double floating point value required by ANSI C standard. It
  5834. will work for non ANSI sun compiler too. */
  5835. #define MAX_FLOATING_POINT_VALUE_FOR_AUTOMATON_BOUND 1.0E37
  5836. /* The function estimate size of the single DFA used by PHR (pipeline
  5837. hazards recognizer). */
  5838. static double
  5839. estimate_one_automaton_bound (void)
  5840. {
  5841. decl_t decl;
  5842. double one_automaton_estimation_bound;
  5843. double root_value;
  5844. int i;
  5845. one_automaton_estimation_bound = 1.0;
  5846. for (i = 0; i < description->decls_num; i++)
  5847. {
  5848. decl = description->decls [i];
  5849. if (decl->mode == dm_unit)
  5850. {
  5851. root_value = exp (log (DECL_UNIT (decl)->max_occ_cycle_num
  5852. - DECL_UNIT (decl)->min_occ_cycle_num + 1.0)
  5853. / automata_num);
  5854. if (MAX_FLOATING_POINT_VALUE_FOR_AUTOMATON_BOUND / root_value
  5855. > one_automaton_estimation_bound)
  5856. one_automaton_estimation_bound *= root_value;
  5857. }
  5858. }
  5859. return one_automaton_estimation_bound;
  5860. }
  5861. /* The function compares unit declarations according to their maximal
  5862. cycle in reservations. */
  5863. static int
  5864. compare_max_occ_cycle_nums (const void *unit_decl_1,
  5865. const void *unit_decl_2)
  5866. {
  5867. if ((DECL_UNIT (*(const_decl_t const*) unit_decl_1)->max_occ_cycle_num)
  5868. < (DECL_UNIT (*(const_decl_t const*) unit_decl_2)->max_occ_cycle_num))
  5869. return 1;
  5870. else if ((DECL_UNIT (*(const_decl_t const*) unit_decl_1)->max_occ_cycle_num)
  5871. == (DECL_UNIT (*(const_decl_t const*) unit_decl_2)->max_occ_cycle_num))
  5872. return 0;
  5873. else
  5874. return -1;
  5875. }
  5876. /* The function makes heuristic assigning automata to units. Actually
  5877. efficacy of the algorithm has been checked yet??? */
  5878. static void
  5879. units_to_automata_heuristic_distr (void)
  5880. {
  5881. double estimation_bound;
  5882. int automaton_num;
  5883. int rest_units_num;
  5884. double bound_value;
  5885. unit_decl_t *unit_decls;
  5886. int i, j;
  5887. if (description->units_num == 0)
  5888. return;
  5889. estimation_bound = estimate_one_automaton_bound ();
  5890. unit_decls = XNEWVEC (unit_decl_t, description->units_num);
  5891. for (i = 0, j = 0; i < description->decls_num; i++)
  5892. if (description->decls[i]->mode == dm_unit)
  5893. unit_decls[j++] = DECL_UNIT (description->decls[i]);
  5894. gcc_assert (j == description->units_num);
  5895. qsort (unit_decls, description->units_num,
  5896. sizeof (unit_decl_t), compare_max_occ_cycle_nums);
  5897. automaton_num = 0;
  5898. bound_value = unit_decls[0]->max_occ_cycle_num;
  5899. unit_decls[0]->corresponding_automaton_num = automaton_num;
  5900. for (i = 1; i < description->units_num; i++)
  5901. {
  5902. rest_units_num = description->units_num - i + 1;
  5903. gcc_assert (automata_num - automaton_num - 1 <= rest_units_num);
  5904. if (automaton_num < automata_num - 1
  5905. && ((automata_num - automaton_num - 1 == rest_units_num)
  5906. || (bound_value
  5907. > (estimation_bound
  5908. / unit_decls[i]->max_occ_cycle_num))))
  5909. {
  5910. bound_value = unit_decls[i]->max_occ_cycle_num;
  5911. automaton_num++;
  5912. }
  5913. else
  5914. bound_value *= unit_decls[i]->max_occ_cycle_num;
  5915. unit_decls[i]->corresponding_automaton_num = automaton_num;
  5916. }
  5917. gcc_assert (automaton_num == automata_num - 1);
  5918. free (unit_decls);
  5919. }
  5920. /* The functions creates automaton insns for each automata. Automaton
  5921. insn is simply insn for given automaton which makes reservation
  5922. only of units of the automaton. */
  5923. static void
  5924. create_ainsns (automaton_t automaton)
  5925. {
  5926. decl_t decl;
  5927. ainsn_t first_ainsn;
  5928. ainsn_t curr_ainsn;
  5929. ainsn_t prev_ainsn;
  5930. int i;
  5931. first_ainsn = NULL;
  5932. prev_ainsn = NULL;
  5933. for (i = 0; i < description->decls_num; i++)
  5934. {
  5935. decl = description->decls [i];
  5936. if (decl->mode == dm_insn_reserv)
  5937. {
  5938. curr_ainsn = XCREATENODE (struct ainsn);
  5939. curr_ainsn->insn_reserv_decl = DECL_INSN_RESERV (decl);
  5940. curr_ainsn->important_p = FALSE;
  5941. curr_ainsn->next_ainsn = NULL;
  5942. if (prev_ainsn == NULL)
  5943. first_ainsn = curr_ainsn;
  5944. else
  5945. prev_ainsn->next_ainsn = curr_ainsn;
  5946. if (decl == advance_cycle_insn_decl)
  5947. automaton->advance_ainsn = curr_ainsn;
  5948. else if (decl == collapse_ndfa_insn_decl)
  5949. automaton->collapse_ainsn = curr_ainsn;
  5950. prev_ainsn = curr_ainsn;
  5951. }
  5952. }
  5953. automaton->ainsn_list = first_ainsn;
  5954. }
  5955. /* The function assigns automata to units according to constructions
  5956. `define_automaton' in the description. */
  5957. static void
  5958. units_to_automata_distr (void)
  5959. {
  5960. decl_t decl;
  5961. int i;
  5962. for (i = 0; i < description->decls_num; i++)
  5963. {
  5964. decl = description->decls [i];
  5965. if (decl->mode == dm_unit)
  5966. {
  5967. if (DECL_UNIT (decl)->automaton_decl == NULL
  5968. || (DECL_UNIT (decl)->automaton_decl->corresponding_automaton
  5969. == NULL))
  5970. /* Distribute to the first automaton. */
  5971. DECL_UNIT (decl)->corresponding_automaton_num = 0;
  5972. else
  5973. DECL_UNIT (decl)->corresponding_automaton_num
  5974. = (DECL_UNIT (decl)->automaton_decl
  5975. ->corresponding_automaton->automaton_order_num);
  5976. }
  5977. }
  5978. }
  5979. /* The function creates DFA(s) for fast pipeline hazards recognition
  5980. after checking and simplifying IR of the description. */
  5981. static void
  5982. create_automata (void)
  5983. {
  5984. automaton_t curr_automaton;
  5985. automaton_t prev_automaton;
  5986. decl_t decl;
  5987. int curr_automaton_num;
  5988. int i;
  5989. if (automata_num != 0)
  5990. {
  5991. units_to_automata_heuristic_distr ();
  5992. for (prev_automaton = NULL, curr_automaton_num = 0;
  5993. curr_automaton_num < automata_num;
  5994. curr_automaton_num++, prev_automaton = curr_automaton)
  5995. {
  5996. curr_automaton = XCREATENODE (struct automaton);
  5997. create_ainsns (curr_automaton);
  5998. curr_automaton->corresponding_automaton_decl = NULL;
  5999. curr_automaton->next_automaton = NULL;
  6000. curr_automaton->automaton_order_num = curr_automaton_num;
  6001. if (prev_automaton == NULL)
  6002. description->first_automaton = curr_automaton;
  6003. else
  6004. prev_automaton->next_automaton = curr_automaton;
  6005. }
  6006. }
  6007. else
  6008. {
  6009. curr_automaton_num = 0;
  6010. prev_automaton = NULL;
  6011. for (i = 0; i < description->decls_num; i++)
  6012. {
  6013. decl = description->decls [i];
  6014. if (decl->mode == dm_automaton
  6015. && DECL_AUTOMATON (decl)->automaton_is_used)
  6016. {
  6017. curr_automaton = XCREATENODE (struct automaton);
  6018. create_ainsns (curr_automaton);
  6019. curr_automaton->corresponding_automaton_decl
  6020. = DECL_AUTOMATON (decl);
  6021. curr_automaton->next_automaton = NULL;
  6022. DECL_AUTOMATON (decl)->corresponding_automaton = curr_automaton;
  6023. curr_automaton->automaton_order_num = curr_automaton_num;
  6024. if (prev_automaton == NULL)
  6025. description->first_automaton = curr_automaton;
  6026. else
  6027. prev_automaton->next_automaton = curr_automaton;
  6028. curr_automaton_num++;
  6029. prev_automaton = curr_automaton;
  6030. }
  6031. }
  6032. if (curr_automaton_num == 0)
  6033. {
  6034. curr_automaton = XCREATENODE (struct automaton);
  6035. create_ainsns (curr_automaton);
  6036. curr_automaton->corresponding_automaton_decl = NULL;
  6037. curr_automaton->next_automaton = NULL;
  6038. description->first_automaton = curr_automaton;
  6039. }
  6040. units_to_automata_distr ();
  6041. }
  6042. NDFA_time = create_ticker ();
  6043. ticker_off (&NDFA_time);
  6044. NDFA_to_DFA_time = create_ticker ();
  6045. ticker_off (&NDFA_to_DFA_time);
  6046. minimize_time = create_ticker ();
  6047. ticker_off (&minimize_time);
  6048. equiv_time = create_ticker ();
  6049. ticker_off (&equiv_time);
  6050. for (curr_automaton = description->first_automaton;
  6051. curr_automaton != NULL;
  6052. curr_automaton = curr_automaton->next_automaton)
  6053. {
  6054. if (progress_flag)
  6055. {
  6056. if (curr_automaton->corresponding_automaton_decl == NULL)
  6057. fprintf (stderr, "Prepare anonymous automaton creation ... ");
  6058. else
  6059. fprintf (stderr, "Prepare automaton `%s' creation...",
  6060. curr_automaton->corresponding_automaton_decl->name);
  6061. }
  6062. create_alt_states (curr_automaton);
  6063. form_ainsn_with_same_reservs (curr_automaton);
  6064. if (progress_flag)
  6065. fprintf (stderr, "done\n");
  6066. build_automaton (curr_automaton);
  6067. enumerate_states (curr_automaton);
  6068. ticker_on (&equiv_time);
  6069. set_insn_equiv_classes (curr_automaton);
  6070. ticker_off (&equiv_time);
  6071. }
  6072. }
  6073. /* This page contains code for forming string representation of
  6074. regexp. The representation is formed on IR obstack. So you should
  6075. not work with IR obstack between regexp_representation and
  6076. finish_regexp_representation calls. */
  6077. /* This recursive function forms string representation of regexp
  6078. (without tailing '\0'). */
  6079. static void
  6080. form_regexp (regexp_t regexp)
  6081. {
  6082. int i;
  6083. switch (regexp->mode)
  6084. {
  6085. case rm_unit: case rm_reserv:
  6086. {
  6087. const char *name = (regexp->mode == rm_unit
  6088. ? REGEXP_UNIT (regexp)->name
  6089. : REGEXP_RESERV (regexp)->name);
  6090. obstack_grow (&irp, name, strlen (name));
  6091. break;
  6092. }
  6093. case rm_sequence:
  6094. for (i = 0; i < REGEXP_SEQUENCE (regexp)->regexps_num; i++)
  6095. {
  6096. if (i != 0)
  6097. obstack_1grow (&irp, ',');
  6098. form_regexp (REGEXP_SEQUENCE (regexp)->regexps [i]);
  6099. }
  6100. break;
  6101. case rm_allof:
  6102. obstack_1grow (&irp, '(');
  6103. for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
  6104. {
  6105. if (i != 0)
  6106. obstack_1grow (&irp, '+');
  6107. if (REGEXP_ALLOF (regexp)->regexps[i]->mode == rm_sequence
  6108. || REGEXP_ALLOF (regexp)->regexps[i]->mode == rm_oneof)
  6109. obstack_1grow (&irp, '(');
  6110. form_regexp (REGEXP_ALLOF (regexp)->regexps [i]);
  6111. if (REGEXP_ALLOF (regexp)->regexps[i]->mode == rm_sequence
  6112. || REGEXP_ALLOF (regexp)->regexps[i]->mode == rm_oneof)
  6113. obstack_1grow (&irp, ')');
  6114. }
  6115. obstack_1grow (&irp, ')');
  6116. break;
  6117. case rm_oneof:
  6118. for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
  6119. {
  6120. if (i != 0)
  6121. obstack_1grow (&irp, '|');
  6122. if (REGEXP_ONEOF (regexp)->regexps[i]->mode == rm_sequence)
  6123. obstack_1grow (&irp, '(');
  6124. form_regexp (REGEXP_ONEOF (regexp)->regexps [i]);
  6125. if (REGEXP_ONEOF (regexp)->regexps[i]->mode == rm_sequence)
  6126. obstack_1grow (&irp, ')');
  6127. }
  6128. break;
  6129. case rm_repeat:
  6130. {
  6131. char digits [30];
  6132. if (REGEXP_REPEAT (regexp)->regexp->mode == rm_sequence
  6133. || REGEXP_REPEAT (regexp)->regexp->mode == rm_allof
  6134. || REGEXP_REPEAT (regexp)->regexp->mode == rm_oneof)
  6135. obstack_1grow (&irp, '(');
  6136. form_regexp (REGEXP_REPEAT (regexp)->regexp);
  6137. if (REGEXP_REPEAT (regexp)->regexp->mode == rm_sequence
  6138. || REGEXP_REPEAT (regexp)->regexp->mode == rm_allof
  6139. || REGEXP_REPEAT (regexp)->regexp->mode == rm_oneof)
  6140. obstack_1grow (&irp, ')');
  6141. sprintf (digits, "*%d", REGEXP_REPEAT (regexp)->repeat_num);
  6142. obstack_grow (&irp, digits, strlen (digits));
  6143. break;
  6144. }
  6145. case rm_nothing:
  6146. obstack_grow (&irp, NOTHING_NAME, strlen (NOTHING_NAME));
  6147. break;
  6148. default:
  6149. gcc_unreachable ();
  6150. }
  6151. }
  6152. /* The function returns string representation of REGEXP on IR
  6153. obstack. */
  6154. static const char *
  6155. regexp_representation (regexp_t regexp)
  6156. {
  6157. form_regexp (regexp);
  6158. obstack_1grow (&irp, '\0');
  6159. return (char *) obstack_base (&irp);
  6160. }
  6161. /* The function frees memory allocated for last formed string
  6162. representation of regexp. */
  6163. static void
  6164. finish_regexp_representation (void)
  6165. {
  6166. int length = obstack_object_size (&irp);
  6167. obstack_blank_fast (&irp, -length);
  6168. }
  6169. /* This page contains code for output PHR (pipeline hazards recognizer). */
  6170. /* The function outputs minimal C type which is sufficient for
  6171. representation numbers in range min_range_value and
  6172. max_range_value. Because host machine and build machine may be
  6173. different, we use here minimal values required by ANSI C standard
  6174. instead of UCHAR_MAX, SHRT_MAX, SHRT_MIN, etc. This is a good
  6175. approximation. */
  6176. static void
  6177. output_range_type (FILE *f, long int min_range_value,
  6178. long int max_range_value)
  6179. {
  6180. if (min_range_value >= 0 && max_range_value <= 255)
  6181. fprintf (f, "unsigned char");
  6182. else if (min_range_value >= -127 && max_range_value <= 127)
  6183. fprintf (f, "signed char");
  6184. else if (min_range_value >= 0 && max_range_value <= 65535)
  6185. fprintf (f, "unsigned short");
  6186. else if (min_range_value >= -32767 && max_range_value <= 32767)
  6187. fprintf (f, "short");
  6188. else
  6189. fprintf (f, "int");
  6190. }
  6191. /* The function outputs all initialization values of VECT. */
  6192. static void
  6193. output_vect (vla_hwint_t vect)
  6194. {
  6195. int els_on_line;
  6196. size_t vect_length = vect.length ();
  6197. size_t i;
  6198. els_on_line = 1;
  6199. if (vect_length == 0)
  6200. fputs ("0 /* This is dummy el because the vect is empty */", output_file);
  6201. else
  6202. for (i = 0; i < vect_length; i++)
  6203. {
  6204. fprintf (output_file, "%5ld", (long) vect[i]);
  6205. if (els_on_line == 10)
  6206. {
  6207. els_on_line = 0;
  6208. fputs (",\n", output_file);
  6209. }
  6210. else if (i < vect_length-1)
  6211. fputs (", ", output_file);
  6212. els_on_line++;
  6213. }
  6214. }
  6215. /* The following is name of the structure which represents DFA(s) for
  6216. PHR. */
  6217. #define CHIP_NAME "DFA_chip"
  6218. /* The following is name of member which represents state of a DFA for
  6219. PHR. */
  6220. static void
  6221. output_chip_member_name (FILE *f, automaton_t automaton)
  6222. {
  6223. if (automaton->corresponding_automaton_decl == NULL)
  6224. fprintf (f, "automaton_state_%d", automaton->automaton_order_num);
  6225. else
  6226. fprintf (f, "%s_automaton_state",
  6227. automaton->corresponding_automaton_decl->name);
  6228. }
  6229. /* The following is name of temporary variable which stores state of a
  6230. DFA for PHR. */
  6231. static void
  6232. output_temp_chip_member_name (FILE *f, automaton_t automaton)
  6233. {
  6234. fprintf (f, "_");
  6235. output_chip_member_name (f, automaton);
  6236. }
  6237. /* This is name of macro value which is code of pseudo_insns
  6238. representing advancing cpu cycle and collapsing the NDFA.
  6239. Its value is used as internal code unknown insn. */
  6240. #define ADVANCE_CYCLE_VALUE_NAME "DFA__ADVANCE_CYCLE"
  6241. #define COLLAPSE_NDFA_VALUE_NAME "NDFA__COLLAPSE"
  6242. /* Output name of translate vector for given automaton. */
  6243. static void
  6244. output_translate_vect_name (FILE *f, automaton_t automaton)
  6245. {
  6246. if (automaton->corresponding_automaton_decl == NULL)
  6247. fprintf (f, "translate_%d", automaton->automaton_order_num);
  6248. else
  6249. fprintf (f, "%s_translate", automaton->corresponding_automaton_decl->name);
  6250. }
  6251. /* Output name for simple transition table representation. */
  6252. static void
  6253. output_trans_full_vect_name (FILE *f, automaton_t automaton)
  6254. {
  6255. if (automaton->corresponding_automaton_decl == NULL)
  6256. fprintf (f, "transitions_%d", automaton->automaton_order_num);
  6257. else
  6258. fprintf (f, "%s_transitions",
  6259. automaton->corresponding_automaton_decl->name);
  6260. }
  6261. /* Output name of comb vector of the transition table for given
  6262. automaton. */
  6263. static void
  6264. output_trans_comb_vect_name (FILE *f, automaton_t automaton)
  6265. {
  6266. if (automaton->corresponding_automaton_decl == NULL)
  6267. fprintf (f, "transitions_%d", automaton->automaton_order_num);
  6268. else
  6269. fprintf (f, "%s_transitions",
  6270. automaton->corresponding_automaton_decl->name);
  6271. }
  6272. /* Output name of check vector of the transition table for given
  6273. automaton. */
  6274. static void
  6275. output_trans_check_vect_name (FILE *f, automaton_t automaton)
  6276. {
  6277. if (automaton->corresponding_automaton_decl == NULL)
  6278. fprintf (f, "check_%d", automaton->automaton_order_num);
  6279. else
  6280. fprintf (f, "%s_check", automaton->corresponding_automaton_decl->name);
  6281. }
  6282. /* Output name of base vector of the transition table for given
  6283. automaton. */
  6284. static void
  6285. output_trans_base_vect_name (FILE *f, automaton_t automaton)
  6286. {
  6287. if (automaton->corresponding_automaton_decl == NULL)
  6288. fprintf (f, "base_%d", automaton->automaton_order_num);
  6289. else
  6290. fprintf (f, "%s_base", automaton->corresponding_automaton_decl->name);
  6291. }
  6292. /* Output name of simple min issue delay table representation. */
  6293. static void
  6294. output_min_issue_delay_vect_name (FILE *f, automaton_t automaton)
  6295. {
  6296. if (automaton->corresponding_automaton_decl == NULL)
  6297. fprintf (f, "min_issue_delay_%d", automaton->automaton_order_num);
  6298. else
  6299. fprintf (f, "%s_min_issue_delay",
  6300. automaton->corresponding_automaton_decl->name);
  6301. }
  6302. /* Output name of deadlock vector for given automaton. */
  6303. static void
  6304. output_dead_lock_vect_name (FILE *f, automaton_t automaton)
  6305. {
  6306. if (automaton->corresponding_automaton_decl == NULL)
  6307. fprintf (f, "dead_lock_%d", automaton->automaton_order_num);
  6308. else
  6309. fprintf (f, "%s_dead_lock", automaton->corresponding_automaton_decl->name);
  6310. }
  6311. /* Output name of reserved units table for AUTOMATON into file F. */
  6312. static void
  6313. output_reserved_units_table_name (FILE *f, automaton_t automaton)
  6314. {
  6315. if (automaton->corresponding_automaton_decl == NULL)
  6316. fprintf (f, "reserved_units_%d", automaton->automaton_order_num);
  6317. else
  6318. fprintf (f, "%s_reserved_units",
  6319. automaton->corresponding_automaton_decl->name);
  6320. }
  6321. /* Name of the PHR interface macro. */
  6322. #define CPU_UNITS_QUERY_MACRO_NAME "CPU_UNITS_QUERY"
  6323. /* Names of an internal functions: */
  6324. #define INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME "internal_min_issue_delay"
  6325. /* This is external type of DFA(s) state. */
  6326. #define STATE_TYPE_NAME "state_t"
  6327. #define INTERNAL_TRANSITION_FUNC_NAME "internal_state_transition"
  6328. #define INTERNAL_RESET_FUNC_NAME "internal_reset"
  6329. #define INTERNAL_DEAD_LOCK_FUNC_NAME "internal_state_dead_lock_p"
  6330. #define INTERNAL_INSN_LATENCY_FUNC_NAME "internal_insn_latency"
  6331. /* Name of cache of insn dfa codes. */
  6332. #define DFA_INSN_CODES_VARIABLE_NAME "dfa_insn_codes"
  6333. /* Name of length of cache of insn dfa codes. */
  6334. #define DFA_INSN_CODES_LENGTH_VARIABLE_NAME "dfa_insn_codes_length"
  6335. /* Names of the PHR interface functions: */
  6336. #define SIZE_FUNC_NAME "state_size"
  6337. #define TRANSITION_FUNC_NAME "state_transition"
  6338. #define MIN_ISSUE_DELAY_FUNC_NAME "min_issue_delay"
  6339. #define MIN_INSN_CONFLICT_DELAY_FUNC_NAME "min_insn_conflict_delay"
  6340. #define DEAD_LOCK_FUNC_NAME "state_dead_lock_p"
  6341. #define RESET_FUNC_NAME "state_reset"
  6342. #define INSN_LATENCY_FUNC_NAME "insn_latency"
  6343. #define PRINT_RESERVATION_FUNC_NAME "print_reservation"
  6344. #define GET_CPU_UNIT_CODE_FUNC_NAME "get_cpu_unit_code"
  6345. #define CPU_UNIT_RESERVATION_P_FUNC_NAME "cpu_unit_reservation_p"
  6346. #define INSN_HAS_DFA_RESERVATION_P_FUNC_NAME "insn_has_dfa_reservation_p"
  6347. #define DFA_CLEAN_INSN_CACHE_FUNC_NAME "dfa_clean_insn_cache"
  6348. #define DFA_CLEAR_SINGLE_INSN_CACHE_FUNC_NAME "dfa_clear_single_insn_cache"
  6349. #define DFA_START_FUNC_NAME "dfa_start"
  6350. #define DFA_FINISH_FUNC_NAME "dfa_finish"
  6351. /* Names of parameters of the PHR interface functions. */
  6352. #define STATE_NAME "state"
  6353. #define INSN_PARAMETER_NAME "insn"
  6354. #define INSN2_PARAMETER_NAME "insn2"
  6355. #define CHIP_PARAMETER_NAME "chip"
  6356. #define FILE_PARAMETER_NAME "f"
  6357. #define CPU_UNIT_NAME_PARAMETER_NAME "cpu_unit_name"
  6358. #define CPU_CODE_PARAMETER_NAME "cpu_unit_code"
  6359. /* Names of the variables whose values are internal insn code of rtx
  6360. insn. */
  6361. #define INTERNAL_INSN_CODE_NAME "insn_code"
  6362. #define INTERNAL_INSN2_CODE_NAME "insn2_code"
  6363. /* Names of temporary variables in some functions. */
  6364. #define TEMPORARY_VARIABLE_NAME "temp"
  6365. #define I_VARIABLE_NAME "i"
  6366. /* Name of result variable in some functions. */
  6367. #define RESULT_VARIABLE_NAME "res"
  6368. /* Name of function (attribute) to translate insn into internal insn
  6369. code. */
  6370. #define INTERNAL_DFA_INSN_CODE_FUNC_NAME "internal_dfa_insn_code"
  6371. /* Name of function (attribute) to translate insn into internal insn
  6372. code with caching. */
  6373. #define DFA_INSN_CODE_FUNC_NAME "dfa_insn_code"
  6374. /* Output C type which is used for representation of codes of states
  6375. of AUTOMATON. */
  6376. static void
  6377. output_state_member_type (FILE *f, automaton_t automaton)
  6378. {
  6379. output_range_type (f, 0, automaton->achieved_states_num);
  6380. }
  6381. /* Output definition of the structure representing current DFA(s)
  6382. state(s). */
  6383. static void
  6384. output_chip_definitions (void)
  6385. {
  6386. automaton_t automaton;
  6387. fprintf (output_file, "struct %s\n{\n", CHIP_NAME);
  6388. for (automaton = description->first_automaton;
  6389. automaton != NULL;
  6390. automaton = automaton->next_automaton)
  6391. {
  6392. fprintf (output_file, " ");
  6393. output_state_member_type (output_file, automaton);
  6394. fprintf (output_file, " ");
  6395. output_chip_member_name (output_file, automaton);
  6396. fprintf (output_file, ";\n");
  6397. }
  6398. fprintf (output_file, "};\n\n");
  6399. #if 0
  6400. fprintf (output_file, "static struct %s %s;\n\n", CHIP_NAME, CHIP_NAME);
  6401. #endif
  6402. }
  6403. /* The function outputs translate vector of internal insn code into
  6404. insn equivalence class number. The equivalence class number is
  6405. used to access to table and vectors representing DFA(s). */
  6406. static void
  6407. output_translate_vect (automaton_t automaton)
  6408. {
  6409. ainsn_t ainsn;
  6410. int insn_value;
  6411. vla_hwint_t translate_vect;
  6412. translate_vect.create (description->insns_num);
  6413. for (insn_value = 0; insn_value < description->insns_num; insn_value++)
  6414. /* Undefined value */
  6415. translate_vect.quick_push (automaton->insn_equiv_classes_num);
  6416. for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn)
  6417. translate_vect[ainsn->insn_reserv_decl->insn_num] =
  6418. ainsn->insn_equiv_class_num;
  6419. fprintf (output_file,
  6420. "/* Vector translating external insn codes to internal ones.*/\n");
  6421. fprintf (output_file, "static const ");
  6422. output_range_type (output_file, 0, automaton->insn_equiv_classes_num);
  6423. fprintf (output_file, " ");
  6424. output_translate_vect_name (output_file, automaton);
  6425. fprintf (output_file, "[] ATTRIBUTE_UNUSED = {\n");
  6426. output_vect (translate_vect);
  6427. fprintf (output_file, "};\n\n");
  6428. translate_vect.release ();
  6429. }
  6430. /* The value in a table state x ainsn -> something which represents
  6431. undefined value. */
  6432. static int undefined_vect_el_value;
  6433. /* The following function returns nonzero value if the best
  6434. representation of the table is comb vector. */
  6435. static int
  6436. comb_vect_p (state_ainsn_table_t tab)
  6437. {
  6438. if (no_comb_flag)
  6439. return false;
  6440. return (2 * tab->full_vect.length () > 5 * tab->comb_vect.length ());
  6441. }
  6442. /* The following function creates new table for AUTOMATON. */
  6443. static state_ainsn_table_t
  6444. create_state_ainsn_table (automaton_t automaton)
  6445. {
  6446. state_ainsn_table_t tab;
  6447. int full_vect_length;
  6448. int i;
  6449. tab = XCREATENODE (struct state_ainsn_table);
  6450. tab->automaton = automaton;
  6451. tab->comb_vect.create (10000);
  6452. tab->check_vect.create (10000);
  6453. tab->base_vect.create (0);
  6454. tab->base_vect.safe_grow (automaton->achieved_states_num);
  6455. full_vect_length = (automaton->insn_equiv_classes_num
  6456. * automaton->achieved_states_num);
  6457. tab->full_vect.create (full_vect_length);
  6458. for (i = 0; i < full_vect_length; i++)
  6459. tab->full_vect.quick_push (undefined_vect_el_value);
  6460. tab->min_base_vect_el_value = 0;
  6461. tab->max_base_vect_el_value = 0;
  6462. tab->min_comb_vect_el_value = 0;
  6463. tab->max_comb_vect_el_value = 0;
  6464. return tab;
  6465. }
  6466. /* The following function outputs the best C representation of the
  6467. table TAB of given TABLE_NAME. */
  6468. static void
  6469. output_state_ainsn_table (state_ainsn_table_t tab, const char *table_name,
  6470. void (*output_full_vect_name_func) (FILE *, automaton_t),
  6471. void (*output_comb_vect_name_func) (FILE *, automaton_t),
  6472. void (*output_check_vect_name_func) (FILE *, automaton_t),
  6473. void (*output_base_vect_name_func) (FILE *, automaton_t))
  6474. {
  6475. if (!comb_vect_p (tab))
  6476. {
  6477. fprintf (output_file, "/* Vector for %s. */\n", table_name);
  6478. fprintf (output_file, "static const ");
  6479. output_range_type (output_file, tab->min_comb_vect_el_value,
  6480. tab->max_comb_vect_el_value);
  6481. fprintf (output_file, " ");
  6482. (*output_full_vect_name_func) (output_file, tab->automaton);
  6483. fprintf (output_file, "[] ATTRIBUTE_UNUSED = {\n");
  6484. output_vect (tab->full_vect);
  6485. fprintf (output_file, "};\n\n");
  6486. }
  6487. else
  6488. {
  6489. fprintf (output_file, "/* Comb vector for %s. */\n", table_name);
  6490. fprintf (output_file, "static const ");
  6491. output_range_type (output_file, tab->min_comb_vect_el_value,
  6492. tab->max_comb_vect_el_value);
  6493. fprintf (output_file, " ");
  6494. (*output_comb_vect_name_func) (output_file, tab->automaton);
  6495. fprintf (output_file, "[] ATTRIBUTE_UNUSED = {\n");
  6496. output_vect (tab->comb_vect);
  6497. fprintf (output_file, "};\n\n");
  6498. fprintf (output_file, "/* Check vector for %s. */\n", table_name);
  6499. fprintf (output_file, "static const ");
  6500. output_range_type (output_file, 0, tab->automaton->achieved_states_num);
  6501. fprintf (output_file, " ");
  6502. (*output_check_vect_name_func) (output_file, tab->automaton);
  6503. fprintf (output_file, "[] = {\n");
  6504. output_vect (tab->check_vect);
  6505. fprintf (output_file, "};\n\n");
  6506. fprintf (output_file, "/* Base vector for %s. */\n", table_name);
  6507. fprintf (output_file, "static const ");
  6508. output_range_type (output_file, tab->min_base_vect_el_value,
  6509. tab->max_base_vect_el_value);
  6510. fprintf (output_file, " ");
  6511. (*output_base_vect_name_func) (output_file, tab->automaton);
  6512. fprintf (output_file, "[] = {\n");
  6513. output_vect (tab->base_vect);
  6514. fprintf (output_file, "};\n\n");
  6515. }
  6516. }
  6517. /* The following function adds vector VECT to table TAB as its line
  6518. with number VECT_NUM. */
  6519. static void
  6520. add_vect (state_ainsn_table_t tab, int vect_num, vla_hwint_t vect)
  6521. {
  6522. int vect_length;
  6523. size_t real_vect_length;
  6524. int comb_vect_index;
  6525. int comb_vect_els_num;
  6526. int vect_index;
  6527. int first_unempty_vect_index;
  6528. int additional_els_num;
  6529. int no_state_value;
  6530. vect_el_t vect_el;
  6531. int i;
  6532. unsigned long vect_mask, comb_vect_mask;
  6533. vect_length = vect.length ();
  6534. gcc_assert (vect_length);
  6535. gcc_assert (vect.last () != undefined_vect_el_value);
  6536. real_vect_length = tab->automaton->insn_equiv_classes_num;
  6537. /* Form full vector in the table: */
  6538. {
  6539. size_t full_base = tab->automaton->insn_equiv_classes_num * vect_num;
  6540. if (tab->full_vect.length () < full_base + vect_length)
  6541. tab->full_vect.safe_grow (full_base + vect_length);
  6542. for (i = 0; i < vect_length; i++)
  6543. tab->full_vect[full_base + i] = vect[i];
  6544. }
  6545. /* The comb_vect min/max values are also used for the full vector, so
  6546. compute them now. */
  6547. for (vect_index = 0; vect_index < vect_length; vect_index++)
  6548. if (vect[vect_index] != undefined_vect_el_value)
  6549. {
  6550. vect_el_t x = vect[vect_index];
  6551. gcc_assert (x >= 0);
  6552. if (tab->max_comb_vect_el_value < x)
  6553. tab->max_comb_vect_el_value = x;
  6554. if (tab->min_comb_vect_el_value > x)
  6555. tab->min_comb_vect_el_value = x;
  6556. }
  6557. if (no_comb_flag)
  6558. return;
  6559. /* Form comb vector in the table: */
  6560. gcc_assert (tab->comb_vect.length () == tab->check_vect.length ());
  6561. comb_vect_els_num = tab->comb_vect.length ();
  6562. for (first_unempty_vect_index = 0;
  6563. first_unempty_vect_index < vect_length;
  6564. first_unempty_vect_index++)
  6565. if (vect[first_unempty_vect_index]
  6566. != undefined_vect_el_value)
  6567. break;
  6568. /* Search for the place in comb vect for the inserted vect. */
  6569. /* Slow case. */
  6570. if (vect_length - first_unempty_vect_index >= SIZEOF_LONG * CHAR_BIT)
  6571. {
  6572. for (comb_vect_index = 0;
  6573. comb_vect_index < comb_vect_els_num;
  6574. comb_vect_index++)
  6575. {
  6576. for (vect_index = first_unempty_vect_index;
  6577. vect_index < vect_length
  6578. && vect_index + comb_vect_index < comb_vect_els_num;
  6579. vect_index++)
  6580. if (vect[vect_index]
  6581. != undefined_vect_el_value
  6582. && (tab->comb_vect[vect_index + comb_vect_index]
  6583. != undefined_vect_el_value))
  6584. break;
  6585. if (vect_index >= vect_length
  6586. || vect_index + comb_vect_index >= comb_vect_els_num)
  6587. break;
  6588. }
  6589. goto found;
  6590. }
  6591. /* Fast case. */
  6592. vect_mask = 0;
  6593. for (vect_index = first_unempty_vect_index;
  6594. vect_index < vect_length;
  6595. vect_index++)
  6596. {
  6597. vect_mask = vect_mask << 1;
  6598. if (vect[vect_index] != undefined_vect_el_value)
  6599. vect_mask |= 1;
  6600. }
  6601. /* Search for the place in comb vect for the inserted vect. */
  6602. comb_vect_index = 0;
  6603. if (comb_vect_els_num == 0)
  6604. goto found;
  6605. comb_vect_mask = 0;
  6606. for (vect_index = first_unempty_vect_index;
  6607. vect_index < vect_length && vect_index < comb_vect_els_num;
  6608. vect_index++)
  6609. {
  6610. comb_vect_mask <<= 1;
  6611. if (vect_index + comb_vect_index < comb_vect_els_num
  6612. && tab->comb_vect[vect_index + comb_vect_index]
  6613. != undefined_vect_el_value)
  6614. comb_vect_mask |= 1;
  6615. }
  6616. if ((vect_mask & comb_vect_mask) == 0)
  6617. goto found;
  6618. for (comb_vect_index = 1, i = vect_length; i < comb_vect_els_num;
  6619. comb_vect_index++, i++)
  6620. {
  6621. comb_vect_mask = (comb_vect_mask << 1) | 1;
  6622. comb_vect_mask ^= (tab->comb_vect[i]
  6623. == undefined_vect_el_value);
  6624. if ((vect_mask & comb_vect_mask) == 0)
  6625. goto found;
  6626. }
  6627. for ( ; comb_vect_index < comb_vect_els_num; comb_vect_index++)
  6628. {
  6629. comb_vect_mask <<= 1;
  6630. if ((vect_mask & comb_vect_mask) == 0)
  6631. goto found;
  6632. }
  6633. found:
  6634. /* Slot was found. */
  6635. additional_els_num = comb_vect_index + real_vect_length - comb_vect_els_num;
  6636. if (additional_els_num < 0)
  6637. additional_els_num = 0;
  6638. /* Expand comb and check vectors. */
  6639. vect_el = undefined_vect_el_value;
  6640. no_state_value = tab->automaton->achieved_states_num;
  6641. while (additional_els_num > 0)
  6642. {
  6643. tab->comb_vect.safe_push (vect_el);
  6644. tab->check_vect.safe_push (no_state_value);
  6645. additional_els_num--;
  6646. }
  6647. gcc_assert (tab->comb_vect.length ()
  6648. >= comb_vect_index + real_vect_length);
  6649. /* Fill comb and check vectors. */
  6650. for (vect_index = 0; vect_index < vect_length; vect_index++)
  6651. if (vect[vect_index] != undefined_vect_el_value)
  6652. {
  6653. vect_el_t x = vect[vect_index];
  6654. gcc_assert (tab->comb_vect[comb_vect_index + vect_index]
  6655. == undefined_vect_el_value);
  6656. gcc_assert (x >= 0);
  6657. tab->comb_vect[comb_vect_index + vect_index] = x;
  6658. tab->check_vect[comb_vect_index + vect_index] = vect_num;
  6659. }
  6660. if (tab->max_comb_vect_el_value < undefined_vect_el_value)
  6661. tab->max_comb_vect_el_value = undefined_vect_el_value;
  6662. if (tab->min_comb_vect_el_value > undefined_vect_el_value)
  6663. tab->min_comb_vect_el_value = undefined_vect_el_value;
  6664. if (tab->max_base_vect_el_value < comb_vect_index)
  6665. tab->max_base_vect_el_value = comb_vect_index;
  6666. if (tab->min_base_vect_el_value > comb_vect_index)
  6667. tab->min_base_vect_el_value = comb_vect_index;
  6668. tab->base_vect[vect_num] = comb_vect_index;
  6669. }
  6670. /* Return number of out arcs of STATE. */
  6671. static int
  6672. out_state_arcs_num (const_state_t state)
  6673. {
  6674. int result;
  6675. arc_t arc;
  6676. result = 0;
  6677. for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
  6678. {
  6679. gcc_assert (arc->insn);
  6680. if (arc->insn->first_ainsn_with_given_equivalence_num)
  6681. result++;
  6682. }
  6683. return result;
  6684. }
  6685. /* Compare number of possible transitions from the states. */
  6686. static int
  6687. compare_transition_els_num (const void *state_ptr_1,
  6688. const void *state_ptr_2)
  6689. {
  6690. const int transition_els_num_1
  6691. = out_state_arcs_num (*(const_state_t const*) state_ptr_1);
  6692. const int transition_els_num_2
  6693. = out_state_arcs_num (*(const_state_t const*) state_ptr_2);
  6694. if (transition_els_num_1 < transition_els_num_2)
  6695. return 1;
  6696. else if (transition_els_num_1 == transition_els_num_2)
  6697. return 0;
  6698. else
  6699. return -1;
  6700. }
  6701. /* The function adds element EL_VALUE to vector VECT for a table state
  6702. x AINSN. */
  6703. static void
  6704. add_vect_el (vla_hwint_t &vect, ainsn_t ainsn, int el_value)
  6705. {
  6706. int equiv_class_num;
  6707. int vect_index;
  6708. gcc_assert (ainsn);
  6709. equiv_class_num = ainsn->insn_equiv_class_num;
  6710. for (vect_index = vect.length ();
  6711. vect_index <= equiv_class_num;
  6712. vect_index++)
  6713. vect.safe_push (undefined_vect_el_value);
  6714. vect[equiv_class_num] = el_value;
  6715. }
  6716. /* This is for forming vector of states of an automaton. */
  6717. static vec<state_t> output_states_vect;
  6718. /* The function is called by function pass_states. The function adds
  6719. STATE to `output_states_vect'. */
  6720. static void
  6721. add_states_vect_el (state_t state)
  6722. {
  6723. output_states_vect.safe_push (state);
  6724. }
  6725. /* Form and output vectors (comb, check, base or full vector)
  6726. representing transition table of AUTOMATON. */
  6727. static void
  6728. output_trans_table (automaton_t automaton)
  6729. {
  6730. size_t i;
  6731. arc_t arc;
  6732. vla_hwint_t transition_vect = vla_hwint_t ();
  6733. undefined_vect_el_value = automaton->achieved_states_num;
  6734. automaton->trans_table = create_state_ainsn_table (automaton);
  6735. /* Create vect of pointers to states ordered by num of transitions
  6736. from the state (state with the maximum num is the first). */
  6737. output_states_vect.create (0);
  6738. pass_states (automaton, add_states_vect_el);
  6739. output_states_vect.qsort (compare_transition_els_num);
  6740. for (i = 0; i < output_states_vect.length (); i++)
  6741. {
  6742. transition_vect.truncate (0);
  6743. for (arc = first_out_arc (output_states_vect[i]);
  6744. arc != NULL;
  6745. arc = next_out_arc (arc))
  6746. {
  6747. gcc_assert (arc->insn);
  6748. if (arc->insn->first_ainsn_with_given_equivalence_num)
  6749. add_vect_el (transition_vect, arc->insn,
  6750. arc->to_state->order_state_num);
  6751. }
  6752. add_vect (automaton->trans_table,
  6753. output_states_vect[i]->order_state_num,
  6754. transition_vect);
  6755. }
  6756. output_state_ainsn_table
  6757. (automaton->trans_table, "state transitions",
  6758. output_trans_full_vect_name, output_trans_comb_vect_name,
  6759. output_trans_check_vect_name, output_trans_base_vect_name);
  6760. output_states_vect.release ();
  6761. transition_vect.release ();
  6762. }
  6763. /* Form and output vectors representing minimal issue delay table of
  6764. AUTOMATON. The table is state x ainsn -> minimal issue delay of
  6765. the ainsn. */
  6766. static void
  6767. output_min_issue_delay_table (automaton_t automaton)
  6768. {
  6769. vla_hwint_t min_issue_delay_vect;
  6770. vla_hwint_t compressed_min_issue_delay_vect;
  6771. ainsn_t ainsn;
  6772. size_t i;
  6773. size_t min_issue_delay_len, compressed_min_issue_delay_len;
  6774. size_t cfactor;
  6775. int changed;
  6776. /* Create vect of pointers to states ordered by num of transitions
  6777. from the state (state with the maximum num is the first). */
  6778. output_states_vect.create (0);
  6779. pass_states (automaton, add_states_vect_el);
  6780. min_issue_delay_len = (output_states_vect.length ()
  6781. * automaton->insn_equiv_classes_num);
  6782. min_issue_delay_vect.create (min_issue_delay_len);
  6783. for (i = 0; i < min_issue_delay_len; i++)
  6784. min_issue_delay_vect.quick_push (-1);
  6785. automaton->max_min_delay = 0;
  6786. do
  6787. {
  6788. size_t state_no;
  6789. changed = 0;
  6790. for (state_no = 0; state_no < output_states_vect.length ();
  6791. state_no++)
  6792. {
  6793. state_t s = output_states_vect[state_no];
  6794. arc_t arc;
  6795. for (arc = first_out_arc (s); arc; arc = next_out_arc (arc))
  6796. {
  6797. int k;
  6798. size_t asn = s->order_state_num
  6799. * automaton->insn_equiv_classes_num
  6800. + arc->insn->insn_equiv_class_num;
  6801. if (min_issue_delay_vect[asn])
  6802. {
  6803. min_issue_delay_vect[asn] = (vect_el_t) 0;
  6804. changed = 1;
  6805. }
  6806. for (k = 0; k < automaton->insn_equiv_classes_num; k++)
  6807. {
  6808. size_t n0, n1;
  6809. vect_el_t delay0, delay1;
  6810. n0 = s->order_state_num
  6811. * automaton->insn_equiv_classes_num
  6812. + k;
  6813. n1 = arc->to_state->order_state_num
  6814. * automaton->insn_equiv_classes_num
  6815. + k;
  6816. delay0 = min_issue_delay_vect[n0];
  6817. delay1 = min_issue_delay_vect[n1];
  6818. if (delay1 != -1)
  6819. {
  6820. if (arc->insn->insn_reserv_decl
  6821. == DECL_INSN_RESERV (advance_cycle_insn_decl))
  6822. delay1++;
  6823. if (delay1 < delay0 || delay0 == -1)
  6824. {
  6825. min_issue_delay_vect[n0] = delay1;
  6826. changed = 1;
  6827. }
  6828. }
  6829. }
  6830. }
  6831. }
  6832. }
  6833. while (changed);
  6834. automaton->max_min_delay = 0;
  6835. for (ainsn = automaton->ainsn_list; ainsn; ainsn = ainsn->next_ainsn)
  6836. if (ainsn->first_ainsn_with_given_equivalence_num)
  6837. {
  6838. for (i = 0; i < output_states_vect.length (); i++)
  6839. {
  6840. state_t s = output_states_vect[i];
  6841. size_t np = s->order_state_num
  6842. * automaton->insn_equiv_classes_num
  6843. + ainsn->insn_equiv_class_num;
  6844. vect_el_t x = min_issue_delay_vect[np];
  6845. if (automaton->max_min_delay < x)
  6846. automaton->max_min_delay = x;
  6847. if (x == -1)
  6848. min_issue_delay_vect[np] = (vect_el_t) 0;
  6849. }
  6850. }
  6851. fprintf (output_file, "/* Vector of min issue delay of insns. */\n");
  6852. fprintf (output_file, "static const ");
  6853. output_range_type (output_file, 0, automaton->max_min_delay);
  6854. fprintf (output_file, " ");
  6855. output_min_issue_delay_vect_name (output_file, automaton);
  6856. fprintf (output_file, "[] ATTRIBUTE_UNUSED = {\n");
  6857. /* Compress the vector. */
  6858. if (automaton->max_min_delay < 2)
  6859. cfactor = 8;
  6860. else if (automaton->max_min_delay < 4)
  6861. cfactor = 4;
  6862. else if (automaton->max_min_delay < 16)
  6863. cfactor = 2;
  6864. else
  6865. cfactor = 1;
  6866. automaton->min_issue_delay_table_compression_factor = cfactor;
  6867. compressed_min_issue_delay_len = (min_issue_delay_len+cfactor-1) / cfactor;
  6868. compressed_min_issue_delay_vect.create (compressed_min_issue_delay_len);
  6869. for (i = 0; i < compressed_min_issue_delay_len; i++)
  6870. compressed_min_issue_delay_vect.quick_push (0);
  6871. for (i = 0; i < min_issue_delay_len; i++)
  6872. {
  6873. size_t ci = i / cfactor;
  6874. vect_el_t x = min_issue_delay_vect[i];
  6875. vect_el_t cx = compressed_min_issue_delay_vect[ci];
  6876. cx |= x << (8 - (i % cfactor + 1) * (8 / cfactor));
  6877. compressed_min_issue_delay_vect[ci] = cx;
  6878. }
  6879. output_vect (compressed_min_issue_delay_vect);
  6880. fprintf (output_file, "};\n\n");
  6881. output_states_vect.release ();
  6882. min_issue_delay_vect.release ();
  6883. compressed_min_issue_delay_vect.release ();
  6884. }
  6885. /* Form and output vector representing the locked states of
  6886. AUTOMATON. */
  6887. static void
  6888. output_dead_lock_vect (automaton_t automaton)
  6889. {
  6890. size_t i;
  6891. arc_t arc;
  6892. vla_hwint_t dead_lock_vect = vla_hwint_t ();
  6893. /* Create vect of pointers to states ordered by num of
  6894. transitions from the state (state with the maximum num is the
  6895. first). */
  6896. automaton->locked_states = 0;
  6897. output_states_vect.create (0);
  6898. pass_states (automaton, add_states_vect_el);
  6899. dead_lock_vect.safe_grow (output_states_vect.length ());
  6900. for (i = 0; i < output_states_vect.length (); i++)
  6901. {
  6902. state_t s = output_states_vect[i];
  6903. arc = first_out_arc (s);
  6904. gcc_assert (arc);
  6905. if (next_out_arc (arc) == NULL
  6906. && (arc->insn->insn_reserv_decl
  6907. == DECL_INSN_RESERV (advance_cycle_insn_decl)))
  6908. {
  6909. dead_lock_vect[s->order_state_num] = 1;
  6910. automaton->locked_states++;
  6911. }
  6912. else
  6913. dead_lock_vect[s->order_state_num] = (vect_el_t) 0;
  6914. }
  6915. if (automaton->locked_states == 0)
  6916. return;
  6917. fprintf (output_file, "/* Vector for locked state flags. */\n");
  6918. fprintf (output_file, "static const ");
  6919. output_range_type (output_file, 0, 1);
  6920. fprintf (output_file, " ");
  6921. output_dead_lock_vect_name (output_file, automaton);
  6922. fprintf (output_file, "[] = {\n");
  6923. output_vect (dead_lock_vect);
  6924. fprintf (output_file, "};\n\n");
  6925. output_states_vect.release ();
  6926. dead_lock_vect.release ();
  6927. }
  6928. /* Form and output vector representing reserved units of the states of
  6929. AUTOMATON. */
  6930. static void
  6931. output_reserved_units_table (automaton_t automaton)
  6932. {
  6933. vla_hwint_t reserved_units_table = vla_hwint_t ();
  6934. int state_byte_size;
  6935. int reserved_units_size;
  6936. size_t n;
  6937. int i;
  6938. if (description->query_units_num == 0)
  6939. return;
  6940. /* Create vect of pointers to states. */
  6941. output_states_vect.create (0);
  6942. pass_states (automaton, add_states_vect_el);
  6943. /* Create vector. */
  6944. state_byte_size = (description->query_units_num + 7) / 8;
  6945. reserved_units_size = (output_states_vect.length ()
  6946. * state_byte_size);
  6947. reserved_units_table.create (reserved_units_size);
  6948. for (i = 0; i < reserved_units_size; i++)
  6949. reserved_units_table.quick_push (0);
  6950. for (n = 0; n < output_states_vect.length (); n++)
  6951. {
  6952. state_t s = output_states_vect[n];
  6953. for (i = 0; i < description->units_num; i++)
  6954. if (units_array [i]->query_p
  6955. && first_cycle_unit_presence (s, i))
  6956. {
  6957. int ri = (s->order_state_num * state_byte_size
  6958. + units_array [i]->query_num / 8);
  6959. vect_el_t x = reserved_units_table[ri];
  6960. x += 1 << (units_array [i]->query_num % 8);
  6961. reserved_units_table[ri] = x;
  6962. }
  6963. }
  6964. fprintf (output_file, "\n#if %s\n", CPU_UNITS_QUERY_MACRO_NAME);
  6965. fprintf (output_file, "/* Vector for reserved units of states. */\n");
  6966. fprintf (output_file, "static const ");
  6967. output_range_type (output_file, 0, 255);
  6968. fprintf (output_file, " ");
  6969. output_reserved_units_table_name (output_file, automaton);
  6970. fprintf (output_file, "[] = {\n");
  6971. output_vect (reserved_units_table);
  6972. fprintf (output_file, "};\n#endif /* #if %s */\n\n",
  6973. CPU_UNITS_QUERY_MACRO_NAME);
  6974. output_states_vect.release ();
  6975. reserved_units_table.release ();
  6976. }
  6977. /* The function outputs all tables representing DFA(s) used for fast
  6978. pipeline hazards recognition. */
  6979. static void
  6980. output_tables (void)
  6981. {
  6982. automaton_t automaton;
  6983. for (automaton = description->first_automaton;
  6984. automaton != NULL;
  6985. automaton = automaton->next_automaton)
  6986. {
  6987. output_translate_vect (automaton);
  6988. output_trans_table (automaton);
  6989. output_min_issue_delay_table (automaton);
  6990. output_dead_lock_vect (automaton);
  6991. output_reserved_units_table (automaton);
  6992. }
  6993. fprintf (output_file, "\n#define %s %d\n\n", ADVANCE_CYCLE_VALUE_NAME,
  6994. DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num);
  6995. if (collapse_flag)
  6996. fprintf (output_file, "\n#define %s %d\n\n", COLLAPSE_NDFA_VALUE_NAME,
  6997. DECL_INSN_RESERV (collapse_ndfa_insn_decl)->insn_num);
  6998. }
  6999. /* The function outputs definition and value of PHR interface variable
  7000. `max_insn_queue_index'. Its value is not less than maximal queue
  7001. length needed for the insn scheduler. */
  7002. static void
  7003. output_max_insn_queue_index_def (void)
  7004. {
  7005. int i, max, latency;
  7006. decl_t decl;
  7007. max = description->max_insn_reserv_cycles;
  7008. for (i = 0; i < description->decls_num; i++)
  7009. {
  7010. decl = description->decls [i];
  7011. if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
  7012. {
  7013. latency = DECL_INSN_RESERV (decl)->default_latency;
  7014. if (latency > max)
  7015. max = latency;
  7016. }
  7017. else if (decl->mode == dm_bypass)
  7018. {
  7019. latency = DECL_BYPASS (decl)->latency;
  7020. if (latency > max)
  7021. max = latency;
  7022. }
  7023. }
  7024. for (i = 0; (1 << i) <= max; i++)
  7025. ;
  7026. gcc_assert (i >= 0);
  7027. fprintf (output_file, "\nconst int max_insn_queue_index = %d;\n\n",
  7028. (1 << i) - 1);
  7029. }
  7030. /* The function outputs switch cases for insn reservations using
  7031. function *output_automata_list_code. */
  7032. static void
  7033. output_insn_code_cases (void (*output_automata_list_code)
  7034. (automata_list_el_t))
  7035. {
  7036. decl_t decl, decl2;
  7037. int i, j;
  7038. for (i = 0; i < description->decls_num; i++)
  7039. {
  7040. decl = description->decls [i];
  7041. if (decl->mode == dm_insn_reserv)
  7042. DECL_INSN_RESERV (decl)->processed_p = FALSE;
  7043. }
  7044. for (i = 0; i < description->decls_num; i++)
  7045. {
  7046. decl = description->decls [i];
  7047. if (decl->mode == dm_insn_reserv
  7048. && !DECL_INSN_RESERV (decl)->processed_p)
  7049. {
  7050. for (j = i; j < description->decls_num; j++)
  7051. {
  7052. decl2 = description->decls [j];
  7053. if (decl2->mode == dm_insn_reserv
  7054. && (DECL_INSN_RESERV (decl2)->important_automata_list
  7055. == DECL_INSN_RESERV (decl)->important_automata_list))
  7056. {
  7057. DECL_INSN_RESERV (decl2)->processed_p = TRUE;
  7058. fprintf (output_file, " case %d: /* %s */\n",
  7059. DECL_INSN_RESERV (decl2)->insn_num,
  7060. DECL_INSN_RESERV (decl2)->name);
  7061. }
  7062. }
  7063. (*output_automata_list_code)
  7064. (DECL_INSN_RESERV (decl)->important_automata_list);
  7065. }
  7066. }
  7067. }
  7068. /* The function outputs a code for evaluation of a minimal delay of
  7069. issue of insns which have reservations in given AUTOMATA_LIST. */
  7070. static void
  7071. output_automata_list_min_issue_delay_code (automata_list_el_t automata_list)
  7072. {
  7073. automata_list_el_t el;
  7074. automaton_t automaton;
  7075. for (el = automata_list; el != NULL; el = el->next_automata_list_el)
  7076. {
  7077. automaton = el->automaton;
  7078. fprintf (output_file, "\n %s = ", TEMPORARY_VARIABLE_NAME);
  7079. output_min_issue_delay_vect_name (output_file, automaton);
  7080. fprintf (output_file,
  7081. (automaton->min_issue_delay_table_compression_factor != 1
  7082. ? " [(" : " ["));
  7083. output_translate_vect_name (output_file, automaton);
  7084. fprintf (output_file, " [%s] + ", INTERNAL_INSN_CODE_NAME);
  7085. fprintf (output_file, "%s->", CHIP_PARAMETER_NAME);
  7086. output_chip_member_name (output_file, automaton);
  7087. fprintf (output_file, " * %d", automaton->insn_equiv_classes_num);
  7088. if (automaton->min_issue_delay_table_compression_factor == 1)
  7089. fprintf (output_file, "];\n");
  7090. else
  7091. {
  7092. fprintf (output_file, ") / %d];\n",
  7093. automaton->min_issue_delay_table_compression_factor);
  7094. fprintf (output_file, " %s = (%s >> (8 - ((",
  7095. TEMPORARY_VARIABLE_NAME, TEMPORARY_VARIABLE_NAME);
  7096. output_translate_vect_name (output_file, automaton);
  7097. fprintf (output_file, " [%s] + ", INTERNAL_INSN_CODE_NAME);
  7098. fprintf (output_file, "%s->", CHIP_PARAMETER_NAME);
  7099. output_chip_member_name (output_file, automaton);
  7100. fprintf (output_file, " * %d)", automaton->insn_equiv_classes_num);
  7101. fprintf
  7102. (output_file, " %% %d + 1) * %d)) & %d;\n",
  7103. automaton->min_issue_delay_table_compression_factor,
  7104. 8 / automaton->min_issue_delay_table_compression_factor,
  7105. (1 << (8 / automaton->min_issue_delay_table_compression_factor))
  7106. - 1);
  7107. }
  7108. if (el == automata_list)
  7109. fprintf (output_file, " %s = %s;\n",
  7110. RESULT_VARIABLE_NAME, TEMPORARY_VARIABLE_NAME);
  7111. else
  7112. {
  7113. fprintf (output_file, " if (%s > %s)\n",
  7114. TEMPORARY_VARIABLE_NAME, RESULT_VARIABLE_NAME);
  7115. fprintf (output_file, " %s = %s;\n",
  7116. RESULT_VARIABLE_NAME, TEMPORARY_VARIABLE_NAME);
  7117. }
  7118. }
  7119. fprintf (output_file, " break;\n\n");
  7120. }
  7121. /* Output function `internal_min_issue_delay'. */
  7122. static void
  7123. output_internal_min_issue_delay_func (void)
  7124. {
  7125. fprintf (output_file,
  7126. "static int\n%s (int %s, struct %s *%s ATTRIBUTE_UNUSED)\n",
  7127. INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
  7128. CHIP_NAME, CHIP_PARAMETER_NAME);
  7129. fprintf (output_file, "{\n int %s ATTRIBUTE_UNUSED;\n int %s = -1;\n",
  7130. TEMPORARY_VARIABLE_NAME, RESULT_VARIABLE_NAME);
  7131. fprintf (output_file, "\n switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME);
  7132. output_insn_code_cases (output_automata_list_min_issue_delay_code);
  7133. fprintf (output_file,
  7134. "\n default:\n %s = -1;\n break;\n }\n",
  7135. RESULT_VARIABLE_NAME);
  7136. fprintf (output_file, " return %s;\n", RESULT_VARIABLE_NAME);
  7137. fprintf (output_file, "}\n\n");
  7138. }
  7139. /* The function outputs a code changing state after issue of insns
  7140. which have reservations in given AUTOMATA_LIST. */
  7141. static void
  7142. output_automata_list_transition_code (automata_list_el_t automata_list)
  7143. {
  7144. automata_list_el_t el, next_el;
  7145. fprintf (output_file, " {\n");
  7146. if (automata_list != NULL && automata_list->next_automata_list_el != NULL)
  7147. for (el = automata_list;; el = next_el)
  7148. {
  7149. next_el = el->next_automata_list_el;
  7150. if (next_el == NULL)
  7151. break;
  7152. fprintf (output_file, " ");
  7153. output_state_member_type (output_file, el->automaton);
  7154. fprintf (output_file, " ");
  7155. output_temp_chip_member_name (output_file, el->automaton);
  7156. fprintf (output_file, ";\n");
  7157. }
  7158. for (el = automata_list; el != NULL; el = el->next_automata_list_el)
  7159. if (comb_vect_p (el->automaton->trans_table))
  7160. {
  7161. fprintf (output_file, "\n %s = ", TEMPORARY_VARIABLE_NAME);
  7162. output_trans_base_vect_name (output_file, el->automaton);
  7163. fprintf (output_file, " [%s->", CHIP_PARAMETER_NAME);
  7164. output_chip_member_name (output_file, el->automaton);
  7165. fprintf (output_file, "] + ");
  7166. output_translate_vect_name (output_file, el->automaton);
  7167. fprintf (output_file, " [%s];\n", INTERNAL_INSN_CODE_NAME);
  7168. fprintf (output_file, " if (");
  7169. output_trans_check_vect_name (output_file, el->automaton);
  7170. fprintf (output_file, " [%s] != %s->",
  7171. TEMPORARY_VARIABLE_NAME, CHIP_PARAMETER_NAME);
  7172. output_chip_member_name (output_file, el->automaton);
  7173. fprintf (output_file, ")\n");
  7174. fprintf (output_file, " return %s (%s, %s);\n",
  7175. INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
  7176. CHIP_PARAMETER_NAME);
  7177. fprintf (output_file, " else\n");
  7178. fprintf (output_file, " ");
  7179. if (el->next_automata_list_el != NULL)
  7180. output_temp_chip_member_name (output_file, el->automaton);
  7181. else
  7182. {
  7183. fprintf (output_file, "%s->", CHIP_PARAMETER_NAME);
  7184. output_chip_member_name (output_file, el->automaton);
  7185. }
  7186. fprintf (output_file, " = ");
  7187. output_trans_comb_vect_name (output_file, el->automaton);
  7188. fprintf (output_file, " [%s];\n", TEMPORARY_VARIABLE_NAME);
  7189. }
  7190. else
  7191. {
  7192. fprintf (output_file, "\n %s = ", TEMPORARY_VARIABLE_NAME);
  7193. output_trans_full_vect_name (output_file, el->automaton);
  7194. fprintf (output_file, " [");
  7195. output_translate_vect_name (output_file, el->automaton);
  7196. fprintf (output_file, " [%s] + ", INTERNAL_INSN_CODE_NAME);
  7197. fprintf (output_file, "%s->", CHIP_PARAMETER_NAME);
  7198. output_chip_member_name (output_file, el->automaton);
  7199. fprintf (output_file, " * %d];\n",
  7200. el->automaton->insn_equiv_classes_num);
  7201. fprintf (output_file, " if (%s >= %d)\n",
  7202. TEMPORARY_VARIABLE_NAME, el->automaton->achieved_states_num);
  7203. fprintf (output_file, " return %s (%s, %s);\n",
  7204. INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
  7205. CHIP_PARAMETER_NAME);
  7206. fprintf (output_file, " else\n ");
  7207. if (el->next_automata_list_el != NULL)
  7208. output_temp_chip_member_name (output_file, el->automaton);
  7209. else
  7210. {
  7211. fprintf (output_file, "%s->", CHIP_PARAMETER_NAME);
  7212. output_chip_member_name (output_file, el->automaton);
  7213. }
  7214. fprintf (output_file, " = %s;\n", TEMPORARY_VARIABLE_NAME);
  7215. }
  7216. if (automata_list != NULL && automata_list->next_automata_list_el != NULL)
  7217. for (el = automata_list;; el = next_el)
  7218. {
  7219. next_el = el->next_automata_list_el;
  7220. if (next_el == NULL)
  7221. break;
  7222. fprintf (output_file, " %s->", CHIP_PARAMETER_NAME);
  7223. output_chip_member_name (output_file, el->automaton);
  7224. fprintf (output_file, " = ");
  7225. output_temp_chip_member_name (output_file, el->automaton);
  7226. fprintf (output_file, ";\n");
  7227. }
  7228. fprintf (output_file, " return -1;\n");
  7229. fprintf (output_file, " }\n");
  7230. }
  7231. /* Output function `internal_state_transition'. */
  7232. static void
  7233. output_internal_trans_func (void)
  7234. {
  7235. fprintf (output_file,
  7236. "static int\n%s (int %s, struct %s *%s ATTRIBUTE_UNUSED)\n",
  7237. INTERNAL_TRANSITION_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
  7238. CHIP_NAME, CHIP_PARAMETER_NAME);
  7239. fprintf (output_file, "{\n int %s ATTRIBUTE_UNUSED;\n", TEMPORARY_VARIABLE_NAME);
  7240. fprintf (output_file, "\n switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME);
  7241. output_insn_code_cases (output_automata_list_transition_code);
  7242. fprintf (output_file, "\n default:\n return -1;\n }\n");
  7243. fprintf (output_file, "}\n\n");
  7244. }
  7245. /* Output code
  7246. if (insn != 0)
  7247. {
  7248. insn_code = dfa_insn_code (insn);
  7249. if (insn_code > DFA__ADVANCE_CYCLE)
  7250. return code;
  7251. }
  7252. else
  7253. insn_code = DFA__ADVANCE_CYCLE;
  7254. where insn denotes INSN_NAME, insn_code denotes INSN_CODE_NAME, and
  7255. code denotes CODE. */
  7256. static void
  7257. output_internal_insn_code_evaluation (const char *insn_name,
  7258. const char *insn_code_name,
  7259. int code)
  7260. {
  7261. fprintf (output_file, "\n if (%s == 0)\n", insn_name);
  7262. fprintf (output_file, " %s = %s;\n\n",
  7263. insn_code_name, ADVANCE_CYCLE_VALUE_NAME);
  7264. if (collapse_flag)
  7265. {
  7266. fprintf (output_file, "\n else if (%s == const0_rtx)\n", insn_name);
  7267. fprintf (output_file, " %s = %s;\n\n",
  7268. insn_code_name, COLLAPSE_NDFA_VALUE_NAME);
  7269. }
  7270. fprintf (output_file, "\n else\n {\n");
  7271. fprintf (output_file,
  7272. " %s = %s (as_a <rtx_insn *> (%s));\n",
  7273. insn_code_name, DFA_INSN_CODE_FUNC_NAME, insn_name);
  7274. fprintf (output_file, " if (%s > %s)\n return %d;\n }\n",
  7275. insn_code_name, ADVANCE_CYCLE_VALUE_NAME, code);
  7276. }
  7277. /* This function outputs `dfa_insn_code' and its helper function
  7278. `dfa_insn_code_enlarge'. */
  7279. static void
  7280. output_dfa_insn_code_func (void)
  7281. {
  7282. /* Emacs c-mode gets really confused if there's a { or } in column 0
  7283. inside a string, so don't do that. */
  7284. fprintf (output_file, "\
  7285. static void\n\
  7286. dfa_insn_code_enlarge (int uid)\n\
  7287. {\n\
  7288. int i = %s;\n\
  7289. %s = 2 * uid;\n\
  7290. %s = XRESIZEVEC (int, %s,\n\
  7291. %s);\n\
  7292. for (; i < %s; i++)\n\
  7293. %s[i] = -1;\n}\n\n",
  7294. DFA_INSN_CODES_LENGTH_VARIABLE_NAME,
  7295. DFA_INSN_CODES_LENGTH_VARIABLE_NAME,
  7296. DFA_INSN_CODES_VARIABLE_NAME, DFA_INSN_CODES_VARIABLE_NAME,
  7297. DFA_INSN_CODES_LENGTH_VARIABLE_NAME,
  7298. DFA_INSN_CODES_LENGTH_VARIABLE_NAME,
  7299. DFA_INSN_CODES_VARIABLE_NAME);
  7300. fprintf (output_file, "\
  7301. static inline int\n%s (rtx_insn *%s)\n\
  7302. {\n\
  7303. int uid = INSN_UID (%s);\n\
  7304. int %s;\n\n",
  7305. DFA_INSN_CODE_FUNC_NAME, INSN_PARAMETER_NAME,
  7306. INSN_PARAMETER_NAME, INTERNAL_INSN_CODE_NAME);
  7307. fprintf (output_file,
  7308. " if (uid >= %s)\n dfa_insn_code_enlarge (uid);\n\n",
  7309. DFA_INSN_CODES_LENGTH_VARIABLE_NAME);
  7310. fprintf (output_file, " %s = %s[uid];\n",
  7311. INTERNAL_INSN_CODE_NAME, DFA_INSN_CODES_VARIABLE_NAME);
  7312. fprintf (output_file, "\
  7313. if (%s < 0)\n\
  7314. {\n\
  7315. %s = %s (%s);\n\
  7316. %s[uid] = %s;\n\
  7317. }\n",
  7318. INTERNAL_INSN_CODE_NAME,
  7319. INTERNAL_INSN_CODE_NAME,
  7320. INTERNAL_DFA_INSN_CODE_FUNC_NAME, INSN_PARAMETER_NAME,
  7321. DFA_INSN_CODES_VARIABLE_NAME, INTERNAL_INSN_CODE_NAME);
  7322. fprintf (output_file, " return %s;\n}\n\n", INTERNAL_INSN_CODE_NAME);
  7323. }
  7324. /* The function outputs PHR interface function `state_transition'. */
  7325. static void
  7326. output_trans_func (void)
  7327. {
  7328. fprintf (output_file, "int\n%s (%s %s, rtx %s)\n",
  7329. TRANSITION_FUNC_NAME, STATE_TYPE_NAME, STATE_NAME,
  7330. INSN_PARAMETER_NAME);
  7331. fprintf (output_file, "{\n int %s;\n", INTERNAL_INSN_CODE_NAME);
  7332. output_internal_insn_code_evaluation (INSN_PARAMETER_NAME,
  7333. INTERNAL_INSN_CODE_NAME, -1);
  7334. fprintf (output_file, " return %s (%s, (struct %s *) %s);\n}\n\n",
  7335. INTERNAL_TRANSITION_FUNC_NAME, INTERNAL_INSN_CODE_NAME, CHIP_NAME, STATE_NAME);
  7336. }
  7337. /* Output function `min_issue_delay'. */
  7338. static void
  7339. output_min_issue_delay_func (void)
  7340. {
  7341. fprintf (output_file, "int\n%s (%s %s, rtx_insn *%s)\n",
  7342. MIN_ISSUE_DELAY_FUNC_NAME, STATE_TYPE_NAME, STATE_NAME,
  7343. INSN_PARAMETER_NAME);
  7344. fprintf (output_file, "{\n int %s;\n", INTERNAL_INSN_CODE_NAME);
  7345. fprintf (output_file, "\n if (%s != 0)\n {\n", INSN_PARAMETER_NAME);
  7346. fprintf (output_file, " %s = %s (%s);\n", INTERNAL_INSN_CODE_NAME,
  7347. DFA_INSN_CODE_FUNC_NAME, INSN_PARAMETER_NAME);
  7348. fprintf (output_file, " if (%s > %s)\n return 0;\n",
  7349. INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
  7350. fprintf (output_file, " }\n else\n %s = %s;\n",
  7351. INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
  7352. fprintf (output_file, "\n return %s (%s, (struct %s *) %s);\n",
  7353. INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
  7354. CHIP_NAME, STATE_NAME);
  7355. fprintf (output_file, "}\n\n");
  7356. }
  7357. /* Output function `internal_dead_lock'. */
  7358. static void
  7359. output_internal_dead_lock_func (void)
  7360. {
  7361. automaton_t automaton;
  7362. fprintf (output_file, "static int\n%s (struct %s *ARG_UNUSED (%s))\n",
  7363. INTERNAL_DEAD_LOCK_FUNC_NAME, CHIP_NAME, CHIP_PARAMETER_NAME);
  7364. fprintf (output_file, "{\n");
  7365. for (automaton = description->first_automaton;
  7366. automaton != NULL;
  7367. automaton = automaton->next_automaton)
  7368. if (automaton->locked_states)
  7369. {
  7370. fprintf (output_file, " if (");
  7371. output_dead_lock_vect_name (output_file, automaton);
  7372. fprintf (output_file, " [%s->", CHIP_PARAMETER_NAME);
  7373. output_chip_member_name (output_file, automaton);
  7374. fprintf (output_file, "])\n return 1/* TRUE */;\n");
  7375. }
  7376. fprintf (output_file, " return 0/* FALSE */;\n}\n\n");
  7377. }
  7378. /* The function outputs PHR interface function `state_dead_lock_p'. */
  7379. static void
  7380. output_dead_lock_func (void)
  7381. {
  7382. fprintf (output_file, "int\n%s (%s %s)\n",
  7383. DEAD_LOCK_FUNC_NAME, STATE_TYPE_NAME, STATE_NAME);
  7384. fprintf (output_file, "{\n return %s ((struct %s *) %s);\n}\n\n",
  7385. INTERNAL_DEAD_LOCK_FUNC_NAME, CHIP_NAME, STATE_NAME);
  7386. }
  7387. /* Output function `internal_reset'. */
  7388. static void
  7389. output_internal_reset_func (void)
  7390. {
  7391. fprintf (output_file, "static inline void\n%s (struct %s *%s)\n",
  7392. INTERNAL_RESET_FUNC_NAME, CHIP_NAME, CHIP_PARAMETER_NAME);
  7393. fprintf (output_file, "{\n memset (%s, 0, sizeof (struct %s));\n}\n\n",
  7394. CHIP_PARAMETER_NAME, CHIP_NAME);
  7395. }
  7396. /* The function outputs PHR interface function `state_size'. */
  7397. static void
  7398. output_size_func (void)
  7399. {
  7400. fprintf (output_file, "int\n%s (void)\n", SIZE_FUNC_NAME);
  7401. fprintf (output_file, "{\n return sizeof (struct %s);\n}\n\n", CHIP_NAME);
  7402. }
  7403. /* The function outputs PHR interface function `state_reset'. */
  7404. static void
  7405. output_reset_func (void)
  7406. {
  7407. fprintf (output_file, "void\n%s (%s %s)\n",
  7408. RESET_FUNC_NAME, STATE_TYPE_NAME, STATE_NAME);
  7409. fprintf (output_file, "{\n %s ((struct %s *) %s);\n}\n\n", INTERNAL_RESET_FUNC_NAME,
  7410. CHIP_NAME, STATE_NAME);
  7411. }
  7412. /* Output function `min_insn_conflict_delay'. */
  7413. static void
  7414. output_min_insn_conflict_delay_func (void)
  7415. {
  7416. fprintf (output_file,
  7417. "int\n%s (%s %s, rtx %s, rtx %s)\n",
  7418. MIN_INSN_CONFLICT_DELAY_FUNC_NAME, STATE_TYPE_NAME,
  7419. STATE_NAME, INSN_PARAMETER_NAME, INSN2_PARAMETER_NAME);
  7420. fprintf (output_file, "{\n struct %s %s;\n int %s, %s, transition;\n",
  7421. CHIP_NAME, CHIP_NAME, INTERNAL_INSN_CODE_NAME,
  7422. INTERNAL_INSN2_CODE_NAME);
  7423. output_internal_insn_code_evaluation (INSN_PARAMETER_NAME,
  7424. INTERNAL_INSN_CODE_NAME, 0);
  7425. output_internal_insn_code_evaluation (INSN2_PARAMETER_NAME,
  7426. INTERNAL_INSN2_CODE_NAME, 0);
  7427. fprintf (output_file, " memcpy (&%s, %s, sizeof (%s));\n",
  7428. CHIP_NAME, STATE_NAME, CHIP_NAME);
  7429. fprintf (output_file, " %s (&%s);\n", INTERNAL_RESET_FUNC_NAME, CHIP_NAME);
  7430. fprintf (output_file, " transition = %s (%s, &%s);\n",
  7431. INTERNAL_TRANSITION_FUNC_NAME, INTERNAL_INSN_CODE_NAME, CHIP_NAME);
  7432. fprintf (output_file, " gcc_assert (transition <= 0);\n");
  7433. fprintf (output_file, " return %s (%s, &%s);\n",
  7434. INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN2_CODE_NAME,
  7435. CHIP_NAME);
  7436. fprintf (output_file, "}\n\n");
  7437. }
  7438. /* Output the array holding default latency values. These are used in
  7439. insn_latency and maximal_insn_latency function implementations. */
  7440. static void
  7441. output_default_latencies (void)
  7442. {
  7443. int i, j, col;
  7444. decl_t decl;
  7445. const char *tabletype = "unsigned char";
  7446. /* Find the smallest integer type that can hold all the default
  7447. latency values. */
  7448. for (i = 0; i < description->decls_num; i++)
  7449. if (description->decls[i]->mode == dm_insn_reserv)
  7450. {
  7451. decl = description->decls[i];
  7452. if (DECL_INSN_RESERV (decl)->default_latency > UCHAR_MAX
  7453. && tabletype[0] != 'i') /* Don't shrink it. */
  7454. tabletype = "unsigned short";
  7455. if (DECL_INSN_RESERV (decl)->default_latency > USHRT_MAX)
  7456. tabletype = "int";
  7457. }
  7458. fprintf (output_file, " static const %s default_latencies[] =\n {",
  7459. tabletype);
  7460. for (i = 0, j = 0, col = 7; i < description->normal_decls_num; i++)
  7461. if (description->decls[i]->mode == dm_insn_reserv)
  7462. {
  7463. if ((col = (col+1) % 8) == 0)
  7464. fputs ("\n ", output_file);
  7465. decl = description->decls[i];
  7466. gcc_assert (j++ == DECL_INSN_RESERV (decl)->insn_num);
  7467. fprintf (output_file, "% 4d,",
  7468. DECL_INSN_RESERV (decl)->default_latency);
  7469. }
  7470. gcc_assert (j == description->insns_num - (collapse_flag ? 2 : 1));
  7471. fputs ("\n };\n", output_file);
  7472. }
  7473. /* Output function `internal_insn_latency'. */
  7474. static void
  7475. output_internal_insn_latency_func (void)
  7476. {
  7477. int i;
  7478. decl_t decl;
  7479. struct bypass_decl *bypass;
  7480. fprintf (output_file, "static int\n%s (int %s ATTRIBUTE_UNUSED,\n\tint %s ATTRIBUTE_UNUSED,\n\trtx %s ATTRIBUTE_UNUSED,\n\trtx %s ATTRIBUTE_UNUSED)\n",
  7481. INTERNAL_INSN_LATENCY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
  7482. INTERNAL_INSN2_CODE_NAME, "insn_or_const0",
  7483. "insn2_or_const0");
  7484. fprintf (output_file, "{\n");
  7485. if (DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num == 0)
  7486. {
  7487. fputs (" return 0;\n}\n\n", output_file);
  7488. return;
  7489. }
  7490. fprintf (output_file, " if (%s >= %s || %s >= %s)\n return 0;\n",
  7491. INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME,
  7492. INTERNAL_INSN2_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
  7493. /* We've now rejected the case that
  7494. INTERNAL_INSN_CODE_NAME >= ADVANCE_CYCLE_VALUE_NAME
  7495. i.e. that
  7496. insn_code >= DFA__ADVANCE_CYCLE,
  7497. and similarly for insn2_code. */
  7498. fprintf (output_file,
  7499. " /* Within output_internal_insn_code_evaluation, the generated\n"
  7500. " code sets \"code\" to NDFA__COLLAPSE for const0_rtx, and\n"
  7501. " NDFA__COLLAPSE > DFA__ADVANCE_CYCLE. Hence we can't be\n"
  7502. " dealing with const0_rtx instances at this point. */\n");
  7503. if (collapse_flag)
  7504. fprintf (output_file,
  7505. " gcc_assert (NDFA__COLLAPSE > DFA__ADVANCE_CYCLE);\n");
  7506. fprintf (output_file,
  7507. (" gcc_assert (insn_or_const0 != const0_rtx);\n"
  7508. " rtx_insn *%s ATTRIBUTE_UNUSED = safe_as_a <rtx_insn *> (insn_or_const0);\n"),
  7509. INSN_PARAMETER_NAME);
  7510. fprintf (output_file,
  7511. (" gcc_assert (insn2_or_const0 != const0_rtx);\n"
  7512. " rtx_insn *%s ATTRIBUTE_UNUSED = safe_as_a <rtx_insn *> (insn2_or_const0);\n"),
  7513. INSN2_PARAMETER_NAME);
  7514. fprintf (output_file, " switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME);
  7515. for (i = 0; i < description->decls_num; i++)
  7516. if (description->decls[i]->mode == dm_insn_reserv
  7517. && DECL_INSN_RESERV (description->decls[i])->bypass_list)
  7518. {
  7519. decl = description->decls [i];
  7520. fprintf (output_file,
  7521. " case %d:\n switch (%s)\n {\n",
  7522. DECL_INSN_RESERV (decl)->insn_num,
  7523. INTERNAL_INSN2_CODE_NAME);
  7524. for (bypass = DECL_INSN_RESERV (decl)->bypass_list;
  7525. bypass != NULL;
  7526. bypass = bypass->next)
  7527. {
  7528. gcc_assert (bypass->in_insn_reserv->insn_num
  7529. != (DECL_INSN_RESERV
  7530. (advance_cycle_insn_decl)->insn_num));
  7531. fprintf (output_file, " case %d:\n",
  7532. bypass->in_insn_reserv->insn_num);
  7533. for (;;)
  7534. {
  7535. if (bypass->bypass_guard_name == NULL)
  7536. {
  7537. gcc_assert (bypass->next == NULL
  7538. || (bypass->in_insn_reserv
  7539. != bypass->next->in_insn_reserv));
  7540. fprintf (output_file, " return %d;\n",
  7541. bypass->latency);
  7542. }
  7543. else
  7544. {
  7545. fprintf (output_file,
  7546. " if (%s (%s, %s))\n",
  7547. bypass->bypass_guard_name, INSN_PARAMETER_NAME,
  7548. INSN2_PARAMETER_NAME);
  7549. fprintf (output_file, " return %d;\n",
  7550. bypass->latency);
  7551. }
  7552. if (bypass->next == NULL
  7553. || bypass->in_insn_reserv != bypass->next->in_insn_reserv)
  7554. break;
  7555. bypass = bypass->next;
  7556. }
  7557. if (bypass->bypass_guard_name != NULL)
  7558. fprintf (output_file, " break;\n");
  7559. }
  7560. fputs (" }\n break;\n", output_file);
  7561. }
  7562. fprintf (output_file, " }\n return default_latencies[%s];\n}\n\n",
  7563. INTERNAL_INSN_CODE_NAME);
  7564. }
  7565. /* Output function `internal_maximum_insn_latency'. */
  7566. static void
  7567. output_internal_maximal_insn_latency_func (void)
  7568. {
  7569. decl_t decl;
  7570. struct bypass_decl *bypass;
  7571. int i;
  7572. int max;
  7573. fprintf (output_file, "static int\n%s (int %s ATTRIBUTE_UNUSED,\n\trtx %s ATTRIBUTE_UNUSED)\n",
  7574. "internal_maximal_insn_latency", INTERNAL_INSN_CODE_NAME,
  7575. INSN_PARAMETER_NAME);
  7576. fprintf (output_file, "{\n");
  7577. if (DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num == 0)
  7578. {
  7579. fputs (" return 0;\n}\n\n", output_file);
  7580. return;
  7581. }
  7582. fprintf (output_file, " switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME);
  7583. for (i = 0; i < description->decls_num; i++)
  7584. if (description->decls[i]->mode == dm_insn_reserv
  7585. && DECL_INSN_RESERV (description->decls[i])->bypass_list)
  7586. {
  7587. decl = description->decls [i];
  7588. max = DECL_INSN_RESERV (decl)->default_latency;
  7589. fprintf (output_file,
  7590. " case %d: {",
  7591. DECL_INSN_RESERV (decl)->insn_num);
  7592. for (bypass = DECL_INSN_RESERV (decl)->bypass_list;
  7593. bypass != NULL;
  7594. bypass = bypass->next)
  7595. {
  7596. if (bypass->latency > max)
  7597. max = bypass->latency;
  7598. }
  7599. fprintf (output_file, " return %d; }\n break;\n", max);
  7600. }
  7601. fprintf (output_file, " }\n return default_latencies[%s];\n}\n\n",
  7602. INTERNAL_INSN_CODE_NAME);
  7603. }
  7604. /* The function outputs PHR interface function `insn_latency'. */
  7605. static void
  7606. output_insn_latency_func (void)
  7607. {
  7608. fprintf (output_file, "int\n%s (rtx %s, rtx %s)\n",
  7609. INSN_LATENCY_FUNC_NAME, INSN_PARAMETER_NAME, INSN2_PARAMETER_NAME);
  7610. fprintf (output_file, "{\n int %s, %s;\n",
  7611. INTERNAL_INSN_CODE_NAME, INTERNAL_INSN2_CODE_NAME);
  7612. output_internal_insn_code_evaluation (INSN_PARAMETER_NAME,
  7613. INTERNAL_INSN_CODE_NAME, 0);
  7614. output_internal_insn_code_evaluation (INSN2_PARAMETER_NAME,
  7615. INTERNAL_INSN2_CODE_NAME, 0);
  7616. fprintf (output_file, " return %s (%s, %s, %s, %s);\n}\n\n",
  7617. INTERNAL_INSN_LATENCY_FUNC_NAME,
  7618. INTERNAL_INSN_CODE_NAME, INTERNAL_INSN2_CODE_NAME,
  7619. INSN_PARAMETER_NAME, INSN2_PARAMETER_NAME);
  7620. }
  7621. /* The function outputs PHR interface function `maximal_insn_latency'. */
  7622. static void
  7623. output_maximal_insn_latency_func (void)
  7624. {
  7625. fprintf (output_file, "int\n%s (rtx %s)\n",
  7626. "maximal_insn_latency", INSN_PARAMETER_NAME);
  7627. fprintf (output_file, "{\n int %s;\n",
  7628. INTERNAL_INSN_CODE_NAME);
  7629. output_internal_insn_code_evaluation (INSN_PARAMETER_NAME,
  7630. INTERNAL_INSN_CODE_NAME, 0);
  7631. fprintf (output_file, " return %s (%s, %s);\n}\n\n",
  7632. "internal_maximal_insn_latency",
  7633. INTERNAL_INSN_CODE_NAME, INSN_PARAMETER_NAME);
  7634. }
  7635. /* The function outputs PHR interface function `print_reservation'. */
  7636. static void
  7637. output_print_reservation_func (void)
  7638. {
  7639. decl_t decl;
  7640. int i, j;
  7641. fprintf (output_file,
  7642. "void\n%s (FILE *%s, rtx_insn *%s ATTRIBUTE_UNUSED)\n{\n",
  7643. PRINT_RESERVATION_FUNC_NAME, FILE_PARAMETER_NAME,
  7644. INSN_PARAMETER_NAME);
  7645. if (DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num == 0)
  7646. {
  7647. fprintf (output_file, " fputs (\"%s\", %s);\n}\n\n",
  7648. NOTHING_NAME, FILE_PARAMETER_NAME);
  7649. return;
  7650. }
  7651. fputs (" static const char *const reservation_names[] =\n {",
  7652. output_file);
  7653. for (i = 0, j = 0; i < description->normal_decls_num; i++)
  7654. {
  7655. decl = description->decls [i];
  7656. if (decl->mode == dm_insn_reserv)
  7657. {
  7658. gcc_assert (j == DECL_INSN_RESERV (decl)->insn_num);
  7659. j++;
  7660. fprintf (output_file, "\n \"%s\",",
  7661. regexp_representation (DECL_INSN_RESERV (decl)->regexp));
  7662. finish_regexp_representation ();
  7663. }
  7664. }
  7665. gcc_assert (j == description->insns_num - (collapse_flag ? 2 : 1));
  7666. fprintf (output_file, "\n \"%s\"\n };\n int %s;\n\n",
  7667. NOTHING_NAME, INTERNAL_INSN_CODE_NAME);
  7668. fprintf (output_file, " if (%s == 0)\n %s = %s;\n",
  7669. INSN_PARAMETER_NAME,
  7670. INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
  7671. fprintf (output_file, " else\n\
  7672. {\n\
  7673. %s = %s (%s);\n\
  7674. if (%s > %s)\n\
  7675. %s = %s;\n\
  7676. }\n",
  7677. INTERNAL_INSN_CODE_NAME, DFA_INSN_CODE_FUNC_NAME,
  7678. INSN_PARAMETER_NAME,
  7679. INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME,
  7680. INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
  7681. fprintf (output_file, " fputs (reservation_names[%s], %s);\n}\n\n",
  7682. INTERNAL_INSN_CODE_NAME, FILE_PARAMETER_NAME);
  7683. }
  7684. /* The following function is used to sort unit declaration by their
  7685. names. */
  7686. static int
  7687. units_cmp (const void *unit1, const void *unit2)
  7688. {
  7689. const_unit_decl_t const u1 = *(const_unit_decl_t const*) unit1;
  7690. const_unit_decl_t const u2 = *(const_unit_decl_t const*) unit2;
  7691. return strcmp (u1->name, u2->name);
  7692. }
  7693. /* The following macro value is name of struct containing unit name
  7694. and unit code. */
  7695. #define NAME_CODE_STRUCT_NAME "name_code"
  7696. /* The following macro value is name of table of struct name_code. */
  7697. #define NAME_CODE_TABLE_NAME "name_code_table"
  7698. /* The following macro values are member names for struct name_code. */
  7699. #define NAME_MEMBER_NAME "name"
  7700. #define CODE_MEMBER_NAME "code"
  7701. /* The following macro values are local variable names for function
  7702. `get_cpu_unit_code'. */
  7703. #define CMP_VARIABLE_NAME "cmp"
  7704. #define LOW_VARIABLE_NAME "l"
  7705. #define MIDDLE_VARIABLE_NAME "m"
  7706. #define HIGH_VARIABLE_NAME "h"
  7707. /* The following function outputs function to obtain internal cpu unit
  7708. code by the cpu unit name. */
  7709. static void
  7710. output_get_cpu_unit_code_func (void)
  7711. {
  7712. int i;
  7713. unit_decl_t *units;
  7714. fprintf (output_file, "int\n%s (const char *%s)\n",
  7715. GET_CPU_UNIT_CODE_FUNC_NAME, CPU_UNIT_NAME_PARAMETER_NAME);
  7716. fprintf (output_file, "{\n struct %s {const char *%s; int %s;};\n",
  7717. NAME_CODE_STRUCT_NAME, NAME_MEMBER_NAME, CODE_MEMBER_NAME);
  7718. fprintf (output_file, " int %s, %s, %s, %s;\n", CMP_VARIABLE_NAME,
  7719. LOW_VARIABLE_NAME, MIDDLE_VARIABLE_NAME, HIGH_VARIABLE_NAME);
  7720. fprintf (output_file, " static struct %s %s [] =\n {\n",
  7721. NAME_CODE_STRUCT_NAME, NAME_CODE_TABLE_NAME);
  7722. units = XNEWVEC (unit_decl_t, description->units_num);
  7723. memcpy (units, units_array, sizeof (unit_decl_t) * description->units_num);
  7724. qsort (units, description->units_num, sizeof (unit_decl_t), units_cmp);
  7725. for (i = 0; i < description->units_num; i++)
  7726. if (units [i]->query_p)
  7727. fprintf (output_file, " {\"%s\", %d},\n",
  7728. units[i]->name, units[i]->query_num);
  7729. fprintf (output_file, " };\n\n");
  7730. fprintf (output_file, " /* The following is binary search: */\n");
  7731. fprintf (output_file, " %s = 0;\n", LOW_VARIABLE_NAME);
  7732. fprintf (output_file, " %s = sizeof (%s) / sizeof (struct %s) - 1;\n",
  7733. HIGH_VARIABLE_NAME, NAME_CODE_TABLE_NAME, NAME_CODE_STRUCT_NAME);
  7734. fprintf (output_file, " while (%s <= %s)\n {\n",
  7735. LOW_VARIABLE_NAME, HIGH_VARIABLE_NAME);
  7736. fprintf (output_file, " %s = (%s + %s) / 2;\n",
  7737. MIDDLE_VARIABLE_NAME, LOW_VARIABLE_NAME, HIGH_VARIABLE_NAME);
  7738. fprintf (output_file, " %s = strcmp (%s, %s [%s].%s);\n",
  7739. CMP_VARIABLE_NAME, CPU_UNIT_NAME_PARAMETER_NAME,
  7740. NAME_CODE_TABLE_NAME, MIDDLE_VARIABLE_NAME, NAME_MEMBER_NAME);
  7741. fprintf (output_file, " if (%s < 0)\n", CMP_VARIABLE_NAME);
  7742. fprintf (output_file, " %s = %s - 1;\n",
  7743. HIGH_VARIABLE_NAME, MIDDLE_VARIABLE_NAME);
  7744. fprintf (output_file, " else if (%s > 0)\n", CMP_VARIABLE_NAME);
  7745. fprintf (output_file, " %s = %s + 1;\n",
  7746. LOW_VARIABLE_NAME, MIDDLE_VARIABLE_NAME);
  7747. fprintf (output_file, " else\n");
  7748. fprintf (output_file, " return %s [%s].%s;\n }\n",
  7749. NAME_CODE_TABLE_NAME, MIDDLE_VARIABLE_NAME, CODE_MEMBER_NAME);
  7750. fprintf (output_file, " return -1;\n}\n\n");
  7751. free (units);
  7752. }
  7753. /* The following function outputs function to check reservation of cpu
  7754. unit (its internal code will be passed as the function argument) in
  7755. given cpu state. */
  7756. static void
  7757. output_cpu_unit_reservation_p (void)
  7758. {
  7759. automaton_t automaton;
  7760. fprintf (output_file, "int\n%s (%s %s, int %s)\n",
  7761. CPU_UNIT_RESERVATION_P_FUNC_NAME,
  7762. STATE_TYPE_NAME, STATE_NAME,
  7763. CPU_CODE_PARAMETER_NAME);
  7764. fprintf (output_file, "{\n gcc_assert (%s >= 0 && %s < %d);\n",
  7765. CPU_CODE_PARAMETER_NAME, CPU_CODE_PARAMETER_NAME,
  7766. description->query_units_num);
  7767. if (description->query_units_num > 0)
  7768. for (automaton = description->first_automaton;
  7769. automaton != NULL;
  7770. automaton = automaton->next_automaton)
  7771. {
  7772. fprintf (output_file, " if ((");
  7773. output_reserved_units_table_name (output_file, automaton);
  7774. fprintf (output_file, " [((struct %s *) %s)->", CHIP_NAME, STATE_NAME);
  7775. output_chip_member_name (output_file, automaton);
  7776. fprintf (output_file, " * %d + %s / 8] >> (%s %% 8)) & 1)\n",
  7777. (description->query_units_num + 7) / 8,
  7778. CPU_CODE_PARAMETER_NAME, CPU_CODE_PARAMETER_NAME);
  7779. fprintf (output_file, " return 1;\n");
  7780. }
  7781. fprintf (output_file, " return 0;\n}\n\n");
  7782. }
  7783. /* The following function outputs a function to check if insn
  7784. has a dfa reservation. */
  7785. static void
  7786. output_insn_has_dfa_reservation_p (void)
  7787. {
  7788. fprintf (output_file,
  7789. "bool\n%s (rtx_insn *%s ATTRIBUTE_UNUSED)\n{\n",
  7790. INSN_HAS_DFA_RESERVATION_P_FUNC_NAME,
  7791. INSN_PARAMETER_NAME);
  7792. if (DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num == 0)
  7793. {
  7794. fprintf (output_file, " return false;\n}\n\n");
  7795. return;
  7796. }
  7797. fprintf (output_file, " int %s;\n\n", INTERNAL_INSN_CODE_NAME);
  7798. fprintf (output_file, " if (%s == 0)\n %s = %s;\n",
  7799. INSN_PARAMETER_NAME,
  7800. INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
  7801. fprintf (output_file, " else\n\
  7802. {\n\
  7803. %s = %s (%s);\n\
  7804. if (%s > %s)\n\
  7805. %s = %s;\n\
  7806. }\n\n",
  7807. INTERNAL_INSN_CODE_NAME, DFA_INSN_CODE_FUNC_NAME,
  7808. INSN_PARAMETER_NAME,
  7809. INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME,
  7810. INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
  7811. fprintf (output_file, " return %s != %s;\n}\n\n",
  7812. INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
  7813. }
  7814. /* The function outputs PHR interface functions `dfa_clean_insn_cache'
  7815. and 'dfa_clear_single_insn_cache'. */
  7816. static void
  7817. output_dfa_clean_insn_cache_func (void)
  7818. {
  7819. fprintf (output_file,
  7820. "void\n%s (void)\n{\n int %s;\n\n",
  7821. DFA_CLEAN_INSN_CACHE_FUNC_NAME, I_VARIABLE_NAME);
  7822. fprintf (output_file,
  7823. " for (%s = 0; %s < %s; %s++)\n %s [%s] = -1;\n}\n\n",
  7824. I_VARIABLE_NAME, I_VARIABLE_NAME,
  7825. DFA_INSN_CODES_LENGTH_VARIABLE_NAME, I_VARIABLE_NAME,
  7826. DFA_INSN_CODES_VARIABLE_NAME, I_VARIABLE_NAME);
  7827. fprintf (output_file,
  7828. "void\n%s (rtx_insn *%s)\n{\n int %s;\n\n",
  7829. DFA_CLEAR_SINGLE_INSN_CACHE_FUNC_NAME, INSN_PARAMETER_NAME,
  7830. I_VARIABLE_NAME);
  7831. fprintf (output_file,
  7832. " %s = INSN_UID (%s);\n if (%s < %s)\n %s [%s] = -1;\n}\n\n",
  7833. I_VARIABLE_NAME, INSN_PARAMETER_NAME, I_VARIABLE_NAME,
  7834. DFA_INSN_CODES_LENGTH_VARIABLE_NAME, DFA_INSN_CODES_VARIABLE_NAME,
  7835. I_VARIABLE_NAME);
  7836. }
  7837. /* The function outputs PHR interface function `dfa_start'. */
  7838. static void
  7839. output_dfa_start_func (void)
  7840. {
  7841. fprintf (output_file,
  7842. "void\n%s (void)\n{\n %s = get_max_uid ();\n",
  7843. DFA_START_FUNC_NAME, DFA_INSN_CODES_LENGTH_VARIABLE_NAME);
  7844. fprintf (output_file, " %s = XNEWVEC (int, %s);\n",
  7845. DFA_INSN_CODES_VARIABLE_NAME, DFA_INSN_CODES_LENGTH_VARIABLE_NAME);
  7846. fprintf (output_file, " %s ();\n}\n\n", DFA_CLEAN_INSN_CACHE_FUNC_NAME);
  7847. }
  7848. /* The function outputs PHR interface function `dfa_finish'. */
  7849. static void
  7850. output_dfa_finish_func (void)
  7851. {
  7852. fprintf (output_file, "void\n%s (void)\n{\n free (%s);\n}\n\n",
  7853. DFA_FINISH_FUNC_NAME, DFA_INSN_CODES_VARIABLE_NAME);
  7854. }
  7855. /* The page contains code for output description file (readable
  7856. representation of original description and generated DFA(s). */
  7857. /* The function outputs string representation of IR reservation. */
  7858. static void
  7859. output_regexp (regexp_t regexp)
  7860. {
  7861. fprintf (output_description_file, "%s", regexp_representation (regexp));
  7862. finish_regexp_representation ();
  7863. }
  7864. /* Output names of units in LIST separated by comma. */
  7865. static void
  7866. output_unit_set_el_list (unit_set_el_t list)
  7867. {
  7868. unit_set_el_t el;
  7869. for (el = list; el != NULL; el = el->next_unit_set_el)
  7870. {
  7871. if (el != list)
  7872. fprintf (output_description_file, ", ");
  7873. fprintf (output_description_file, "%s", el->unit_decl->name);
  7874. }
  7875. }
  7876. /* Output patterns in LIST separated by comma. */
  7877. static void
  7878. output_pattern_set_el_list (pattern_set_el_t list)
  7879. {
  7880. pattern_set_el_t el;
  7881. int i;
  7882. for (el = list; el != NULL; el = el->next_pattern_set_el)
  7883. {
  7884. if (el != list)
  7885. fprintf (output_description_file, ", ");
  7886. for (i = 0; i < el->units_num; i++)
  7887. fprintf (output_description_file, (i == 0 ? "%s" : " %s"),
  7888. el->unit_decls [i]->name);
  7889. }
  7890. }
  7891. /* The function outputs string representation of IR define_reservation
  7892. and define_insn_reservation. */
  7893. static void
  7894. output_description (void)
  7895. {
  7896. decl_t decl;
  7897. int i;
  7898. for (i = 0; i < description->decls_num; i++)
  7899. {
  7900. decl = description->decls [i];
  7901. if (decl->mode == dm_unit)
  7902. {
  7903. if (DECL_UNIT (decl)->excl_list != NULL)
  7904. {
  7905. fprintf (output_description_file, "unit %s exclusion_set: ",
  7906. DECL_UNIT (decl)->name);
  7907. output_unit_set_el_list (DECL_UNIT (decl)->excl_list);
  7908. fprintf (output_description_file, "\n");
  7909. }
  7910. if (DECL_UNIT (decl)->presence_list != NULL)
  7911. {
  7912. fprintf (output_description_file, "unit %s presence_set: ",
  7913. DECL_UNIT (decl)->name);
  7914. output_pattern_set_el_list (DECL_UNIT (decl)->presence_list);
  7915. fprintf (output_description_file, "\n");
  7916. }
  7917. if (DECL_UNIT (decl)->final_presence_list != NULL)
  7918. {
  7919. fprintf (output_description_file, "unit %s final_presence_set: ",
  7920. DECL_UNIT (decl)->name);
  7921. output_pattern_set_el_list
  7922. (DECL_UNIT (decl)->final_presence_list);
  7923. fprintf (output_description_file, "\n");
  7924. }
  7925. if (DECL_UNIT (decl)->absence_list != NULL)
  7926. {
  7927. fprintf (output_description_file, "unit %s absence_set: ",
  7928. DECL_UNIT (decl)->name);
  7929. output_pattern_set_el_list (DECL_UNIT (decl)->absence_list);
  7930. fprintf (output_description_file, "\n");
  7931. }
  7932. if (DECL_UNIT (decl)->final_absence_list != NULL)
  7933. {
  7934. fprintf (output_description_file, "unit %s final_absence_set: ",
  7935. DECL_UNIT (decl)->name);
  7936. output_pattern_set_el_list
  7937. (DECL_UNIT (decl)->final_absence_list);
  7938. fprintf (output_description_file, "\n");
  7939. }
  7940. }
  7941. }
  7942. fprintf (output_description_file, "\n");
  7943. for (i = 0; i < description->normal_decls_num; i++)
  7944. {
  7945. decl = description->decls [i];
  7946. if (decl->mode == dm_reserv)
  7947. {
  7948. fprintf (output_description_file, "reservation %s: ",
  7949. DECL_RESERV (decl)->name);
  7950. output_regexp (DECL_RESERV (decl)->regexp);
  7951. fprintf (output_description_file, "\n");
  7952. }
  7953. else if (decl->mode == dm_insn_reserv)
  7954. {
  7955. fprintf (output_description_file, "insn reservation %s ",
  7956. DECL_INSN_RESERV (decl)->name);
  7957. print_rtl (output_description_file,
  7958. DECL_INSN_RESERV (decl)->condexp);
  7959. fprintf (output_description_file, ": ");
  7960. output_regexp (DECL_INSN_RESERV (decl)->regexp);
  7961. fprintf (output_description_file, "\n");
  7962. }
  7963. else if (decl->mode == dm_bypass)
  7964. fprintf (output_description_file, "bypass %d %s %s\n",
  7965. DECL_BYPASS (decl)->latency,
  7966. DECL_BYPASS (decl)->out_pattern,
  7967. DECL_BYPASS (decl)->in_pattern);
  7968. }
  7969. fprintf (output_description_file, "\n\f\n");
  7970. }
  7971. /* The function outputs name of AUTOMATON. */
  7972. static void
  7973. output_automaton_name (FILE *f, automaton_t automaton)
  7974. {
  7975. if (automaton->corresponding_automaton_decl == NULL)
  7976. fprintf (f, "#%d", automaton->automaton_order_num);
  7977. else
  7978. fprintf (f, "`%s'", automaton->corresponding_automaton_decl->name);
  7979. }
  7980. /* Maximal length of line for pretty printing into description
  7981. file. */
  7982. #define MAX_LINE_LENGTH 70
  7983. /* The function outputs units name belonging to AUTOMATON. */
  7984. static void
  7985. output_automaton_units (automaton_t automaton)
  7986. {
  7987. decl_t decl;
  7988. const char *name;
  7989. int curr_line_length;
  7990. int there_is_an_automaton_unit;
  7991. int i;
  7992. fprintf (output_description_file, "\n Corresponding units:\n");
  7993. fprintf (output_description_file, " ");
  7994. curr_line_length = 4;
  7995. there_is_an_automaton_unit = 0;
  7996. for (i = 0; i < description->decls_num; i++)
  7997. {
  7998. decl = description->decls [i];
  7999. if (decl->mode == dm_unit
  8000. && (DECL_UNIT (decl)->corresponding_automaton_num
  8001. == automaton->automaton_order_num))
  8002. {
  8003. there_is_an_automaton_unit = 1;
  8004. name = DECL_UNIT (decl)->name;
  8005. if (curr_line_length + strlen (name) + 1 > MAX_LINE_LENGTH )
  8006. {
  8007. curr_line_length = strlen (name) + 4;
  8008. fprintf (output_description_file, "\n ");
  8009. }
  8010. else
  8011. {
  8012. curr_line_length += strlen (name) + 1;
  8013. fprintf (output_description_file, " ");
  8014. }
  8015. fprintf (output_description_file, "%s", name);
  8016. }
  8017. }
  8018. if (!there_is_an_automaton_unit)
  8019. fprintf (output_description_file, "<None>");
  8020. fprintf (output_description_file, "\n\n");
  8021. }
  8022. /* The following variable is used for forming array of all possible cpu unit
  8023. reservations described by the current DFA state. */
  8024. static vec<reserv_sets_t> state_reservs;
  8025. /* The function forms `state_reservs' for STATE. */
  8026. static void
  8027. add_state_reservs (state_t state)
  8028. {
  8029. alt_state_t curr_alt_state;
  8030. if (state->component_states != NULL)
  8031. for (curr_alt_state = state->component_states;
  8032. curr_alt_state != NULL;
  8033. curr_alt_state = curr_alt_state->next_sorted_alt_state)
  8034. add_state_reservs (curr_alt_state->state);
  8035. else
  8036. state_reservs.safe_push (state->reservs);
  8037. }
  8038. /* The function outputs readable representation of all out arcs of
  8039. STATE. */
  8040. static void
  8041. output_state_arcs (state_t state)
  8042. {
  8043. arc_t arc;
  8044. ainsn_t ainsn;
  8045. const char *insn_name;
  8046. int curr_line_length;
  8047. for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
  8048. {
  8049. ainsn = arc->insn;
  8050. gcc_assert (ainsn->first_insn_with_same_reservs);
  8051. fprintf (output_description_file, " ");
  8052. curr_line_length = 7;
  8053. fprintf (output_description_file, "%2d: ", ainsn->insn_equiv_class_num);
  8054. do
  8055. {
  8056. insn_name = ainsn->insn_reserv_decl->name;
  8057. if (curr_line_length + strlen (insn_name) > MAX_LINE_LENGTH)
  8058. {
  8059. if (ainsn != arc->insn)
  8060. {
  8061. fprintf (output_description_file, ",\n ");
  8062. curr_line_length = strlen (insn_name) + 6;
  8063. }
  8064. else
  8065. curr_line_length += strlen (insn_name);
  8066. }
  8067. else
  8068. {
  8069. curr_line_length += strlen (insn_name);
  8070. if (ainsn != arc->insn)
  8071. {
  8072. curr_line_length += 2;
  8073. fprintf (output_description_file, ", ");
  8074. }
  8075. }
  8076. fprintf (output_description_file, "%s", insn_name);
  8077. ainsn = ainsn->next_same_reservs_insn;
  8078. }
  8079. while (ainsn != NULL);
  8080. fprintf (output_description_file, " %d \n",
  8081. arc->to_state->order_state_num);
  8082. }
  8083. fprintf (output_description_file, "\n");
  8084. }
  8085. /* The following function is used for sorting possible cpu unit
  8086. reservation of a DFA state. */
  8087. static int
  8088. state_reservs_cmp (const void *reservs_ptr_1, const void *reservs_ptr_2)
  8089. {
  8090. return reserv_sets_cmp (*(const_reserv_sets_t const*) reservs_ptr_1,
  8091. *(const_reserv_sets_t const*) reservs_ptr_2);
  8092. }
  8093. /* The following function is used for sorting possible cpu unit
  8094. reservation of a DFA state. */
  8095. static void
  8096. remove_state_duplicate_reservs (void)
  8097. {
  8098. size_t i, j;
  8099. for (i = 1, j = 0; i < state_reservs.length (); i++)
  8100. if (reserv_sets_cmp (state_reservs[j], state_reservs[i]))
  8101. {
  8102. j++;
  8103. state_reservs[j] = state_reservs[i];
  8104. }
  8105. state_reservs.truncate (j + 1);
  8106. }
  8107. /* The following function output readable representation of DFA(s)
  8108. state used for fast recognition of pipeline hazards. State is
  8109. described by possible (current and scheduled) cpu unit
  8110. reservations. */
  8111. static void
  8112. output_state (state_t state)
  8113. {
  8114. size_t i;
  8115. state_reservs.create (0);
  8116. fprintf (output_description_file, " State #%d", state->order_state_num);
  8117. fprintf (output_description_file,
  8118. state->new_cycle_p ? " (new cycle)\n" : "\n");
  8119. add_state_reservs (state);
  8120. state_reservs.qsort (state_reservs_cmp);
  8121. remove_state_duplicate_reservs ();
  8122. for (i = 0; i < state_reservs.length (); i++)
  8123. {
  8124. fprintf (output_description_file, " ");
  8125. output_reserv_sets (output_description_file, state_reservs[i]);
  8126. fprintf (output_description_file, "\n");
  8127. }
  8128. fprintf (output_description_file, "\n");
  8129. output_state_arcs (state);
  8130. state_reservs.release ();
  8131. }
  8132. /* The following function output readable representation of
  8133. DFAs used for fast recognition of pipeline hazards. */
  8134. static void
  8135. output_automaton_descriptions (void)
  8136. {
  8137. automaton_t automaton;
  8138. for (automaton = description->first_automaton;
  8139. automaton != NULL;
  8140. automaton = automaton->next_automaton)
  8141. {
  8142. fprintf (output_description_file, "\nAutomaton ");
  8143. output_automaton_name (output_description_file, automaton);
  8144. fprintf (output_description_file, "\n");
  8145. output_automaton_units (automaton);
  8146. pass_states (automaton, output_state);
  8147. }
  8148. }
  8149. /* The page contains top level function for generation DFA(s) used for
  8150. PHR. */
  8151. /* The function outputs statistics about work of different phases of
  8152. DFA generator. */
  8153. static void
  8154. output_statistics (FILE *f)
  8155. {
  8156. automaton_t automaton;
  8157. int states_num;
  8158. #ifndef NDEBUG
  8159. int transition_comb_vect_els = 0;
  8160. int transition_full_vect_els = 0;
  8161. int min_issue_delay_vect_els = 0;
  8162. int locked_states = 0;
  8163. #endif
  8164. for (automaton = description->first_automaton;
  8165. automaton != NULL;
  8166. automaton = automaton->next_automaton)
  8167. {
  8168. fprintf (f, "\nAutomaton ");
  8169. output_automaton_name (f, automaton);
  8170. fprintf (f, "\n %5d NDFA states, %5d NDFA arcs\n",
  8171. automaton->NDFA_states_num, automaton->NDFA_arcs_num);
  8172. fprintf (f, " %5d DFA states, %5d DFA arcs\n",
  8173. automaton->DFA_states_num, automaton->DFA_arcs_num);
  8174. states_num = automaton->DFA_states_num;
  8175. if (!no_minimization_flag)
  8176. {
  8177. fprintf (f, " %5d minimal DFA states, %5d minimal DFA arcs\n",
  8178. automaton->minimal_DFA_states_num,
  8179. automaton->minimal_DFA_arcs_num);
  8180. states_num = automaton->minimal_DFA_states_num;
  8181. }
  8182. fprintf (f, " %5d all insns %5d insn equivalence classes\n",
  8183. description->insns_num, automaton->insn_equiv_classes_num);
  8184. fprintf (f, " %d locked states\n", automaton->locked_states);
  8185. #ifndef NDEBUG
  8186. fprintf
  8187. (f, "%5ld transition comb vector els, %5ld trans table els: %s\n",
  8188. (long) automaton->trans_table->comb_vect.length (),
  8189. (long) automaton->trans_table->full_vect.length (),
  8190. (comb_vect_p (automaton->trans_table)
  8191. ? "use comb vect" : "use simple vect"));
  8192. fprintf
  8193. (f, "%5ld min delay table els, compression factor %d\n",
  8194. (long) states_num * automaton->insn_equiv_classes_num,
  8195. automaton->min_issue_delay_table_compression_factor);
  8196. transition_comb_vect_els
  8197. += automaton->trans_table->comb_vect.length ();
  8198. transition_full_vect_els
  8199. += automaton->trans_table->full_vect.length ();
  8200. min_issue_delay_vect_els
  8201. += states_num * automaton->insn_equiv_classes_num;
  8202. locked_states
  8203. += automaton->locked_states;
  8204. #endif
  8205. }
  8206. #ifndef NDEBUG
  8207. fprintf (f, "\n%5d all allocated states, %5d all allocated arcs\n",
  8208. allocated_states_num, allocated_arcs_num);
  8209. fprintf (f, "%5d all allocated alternative states\n",
  8210. allocated_alt_states_num);
  8211. fprintf (f, "%5d all transition comb vector els, %5d all trans table els\n",
  8212. transition_comb_vect_els, transition_full_vect_els);
  8213. fprintf (f, "%5d all min delay table els\n", min_issue_delay_vect_els);
  8214. fprintf (f, "%5d all locked states\n", locked_states);
  8215. #endif
  8216. }
  8217. /* The function output times of work of different phases of DFA
  8218. generator. */
  8219. static void
  8220. output_time_statistics (FILE *f)
  8221. {
  8222. fprintf (f, "\n transformation: ");
  8223. print_active_time (f, transform_time);
  8224. fprintf (f, (!ndfa_flag ? ", building DFA: " : ", building NDFA: "));
  8225. print_active_time (f, NDFA_time);
  8226. if (ndfa_flag)
  8227. {
  8228. fprintf (f, ", NDFA -> DFA: ");
  8229. print_active_time (f, NDFA_to_DFA_time);
  8230. }
  8231. fprintf (f, "\n DFA minimization: ");
  8232. print_active_time (f, minimize_time);
  8233. fprintf (f, ", making insn equivalence: ");
  8234. print_active_time (f, equiv_time);
  8235. fprintf (f, "\n all automaton generation: ");
  8236. print_active_time (f, automaton_generation_time);
  8237. fprintf (f, ", output: ");
  8238. print_active_time (f, output_time);
  8239. fprintf (f, "\n");
  8240. }
  8241. /* The function generates DFA (deterministic finite state automaton)
  8242. for fast recognition of pipeline hazards. No errors during
  8243. checking must be fixed before this function call. */
  8244. static void
  8245. generate (void)
  8246. {
  8247. automata_num = split_argument;
  8248. if (description->units_num < automata_num)
  8249. automata_num = description->units_num;
  8250. initiate_states ();
  8251. initiate_arcs ();
  8252. initiate_automata_lists ();
  8253. initiate_pass_states ();
  8254. initiate_excl_sets ();
  8255. initiate_presence_absence_pattern_sets ();
  8256. automaton_generation_time = create_ticker ();
  8257. create_automata ();
  8258. ticker_off (&automaton_generation_time);
  8259. }
  8260. /* This page mainly contains top level functions of pipeline hazards
  8261. description translator. */
  8262. /* The following macro value is suffix of name of description file of
  8263. pipeline hazards description translator. */
  8264. #define STANDARD_OUTPUT_DESCRIPTION_FILE_SUFFIX ".dfa"
  8265. /* The function returns suffix of given file name. The returned
  8266. string can not be changed. */
  8267. static const char *
  8268. file_name_suffix (const char *file_name)
  8269. {
  8270. const char *last_period;
  8271. for (last_period = NULL; *file_name != '\0'; file_name++)
  8272. if (*file_name == '.')
  8273. last_period = file_name;
  8274. return (last_period == NULL ? file_name : last_period);
  8275. }
  8276. /* The function returns base name of given file name, i.e. pointer to
  8277. first char after last `/' (or `\' for WIN32) in given file name,
  8278. given file name itself if the directory name is absent. The
  8279. returned string can not be changed. */
  8280. static const char *
  8281. base_file_name (const char *file_name)
  8282. {
  8283. int directory_name_length;
  8284. directory_name_length = strlen (file_name);
  8285. #ifdef WIN32
  8286. while (directory_name_length >= 0 && file_name[directory_name_length] != '/'
  8287. && file_name[directory_name_length] != '\\')
  8288. #else
  8289. while (directory_name_length >= 0 && file_name[directory_name_length] != '/')
  8290. #endif
  8291. directory_name_length--;
  8292. return file_name + directory_name_length + 1;
  8293. }
  8294. /* A function passed as argument to init_rtx_reader_args_cb. It parses the
  8295. options available for genautomata. Returns true if the option was
  8296. recognized. */
  8297. static bool
  8298. parse_automata_opt (const char *str)
  8299. {
  8300. if (strcmp (str, NO_MINIMIZATION_OPTION) == 0)
  8301. no_minimization_flag = 1;
  8302. else if (strcmp (str, TIME_OPTION) == 0)
  8303. time_flag = 1;
  8304. else if (strcmp (str, STATS_OPTION) == 0)
  8305. stats_flag = 1;
  8306. else if (strcmp (str, V_OPTION) == 0)
  8307. v_flag = 1;
  8308. else if (strcmp (str, W_OPTION) == 0)
  8309. w_flag = 1;
  8310. else if (strcmp (str, NDFA_OPTION) == 0)
  8311. ndfa_flag = 1;
  8312. else if (strcmp (str, COLLAPSE_OPTION) == 0)
  8313. collapse_flag = 1;
  8314. else if (strcmp (str, PROGRESS_OPTION) == 0)
  8315. progress_flag = 1;
  8316. else if (strcmp (str, "-split") == 0)
  8317. {
  8318. fatal ("option `-split' has not been implemented yet\n");
  8319. /* split_argument = atoi (argument_vect [i + 1]); */
  8320. }
  8321. else
  8322. return false;
  8323. return true;
  8324. }
  8325. /* The following is top level function to initialize the work of
  8326. pipeline hazards description translator. */
  8327. static void
  8328. initiate_automaton_gen (char **argv)
  8329. {
  8330. const char *base_name;
  8331. /* Initialize IR storage. */
  8332. obstack_init (&irp);
  8333. initiate_automaton_decl_table ();
  8334. initiate_insn_decl_table ();
  8335. initiate_decl_table ();
  8336. output_file = stdout;
  8337. output_description_file = NULL;
  8338. base_name = base_file_name (argv[1]);
  8339. obstack_grow (&irp, base_name,
  8340. strlen (base_name) - strlen (file_name_suffix (base_name)));
  8341. obstack_grow (&irp, STANDARD_OUTPUT_DESCRIPTION_FILE_SUFFIX,
  8342. strlen (STANDARD_OUTPUT_DESCRIPTION_FILE_SUFFIX) + 1);
  8343. obstack_1grow (&irp, '\0');
  8344. output_description_file_name = (char *) obstack_base (&irp);
  8345. obstack_finish (&irp);
  8346. }
  8347. /* The following function checks existence at least one arc marked by
  8348. each insn. */
  8349. static void
  8350. check_automata_insn_issues (void)
  8351. {
  8352. automaton_t automaton;
  8353. ainsn_t ainsn, reserv_ainsn;
  8354. for (automaton = description->first_automaton;
  8355. automaton != NULL;
  8356. automaton = automaton->next_automaton)
  8357. {
  8358. for (ainsn = automaton->ainsn_list;
  8359. ainsn != NULL;
  8360. ainsn = ainsn->next_ainsn)
  8361. if (ainsn->first_insn_with_same_reservs && !ainsn->arc_exists_p
  8362. && ainsn != automaton->collapse_ainsn)
  8363. {
  8364. for (reserv_ainsn = ainsn;
  8365. reserv_ainsn != NULL;
  8366. reserv_ainsn = reserv_ainsn->next_same_reservs_insn)
  8367. if (automaton->corresponding_automaton_decl != NULL)
  8368. {
  8369. if (!w_flag)
  8370. error ("Automaton `%s': Insn `%s' will never be issued",
  8371. automaton->corresponding_automaton_decl->name,
  8372. reserv_ainsn->insn_reserv_decl->name);
  8373. else
  8374. warning ("Automaton `%s': Insn `%s' will never be issued",
  8375. automaton->corresponding_automaton_decl->name,
  8376. reserv_ainsn->insn_reserv_decl->name);
  8377. }
  8378. else
  8379. {
  8380. if (!w_flag)
  8381. error ("Insn `%s' will never be issued",
  8382. reserv_ainsn->insn_reserv_decl->name);
  8383. else
  8384. warning ("Insn `%s' will never be issued",
  8385. reserv_ainsn->insn_reserv_decl->name);
  8386. }
  8387. }
  8388. }
  8389. }
  8390. /* The following vla is used for storing pointers to all achieved
  8391. states. */
  8392. static vec<state_t> automaton_states;
  8393. /* This function is called by function pass_states to add an achieved
  8394. STATE. */
  8395. static void
  8396. add_automaton_state (state_t state)
  8397. {
  8398. automaton_states.safe_push (state);
  8399. }
  8400. /* The following function forms list of important automata (whose
  8401. states may be changed after the insn issue) for each insn. */
  8402. static void
  8403. form_important_insn_automata_lists (void)
  8404. {
  8405. automaton_t automaton;
  8406. decl_t decl;
  8407. ainsn_t ainsn;
  8408. arc_t arc;
  8409. int i;
  8410. size_t n;
  8411. automaton_states.create (0);
  8412. /* Mark important ainsns. */
  8413. for (automaton = description->first_automaton;
  8414. automaton != NULL;
  8415. automaton = automaton->next_automaton)
  8416. {
  8417. automaton_states.truncate (0);
  8418. pass_states (automaton, add_automaton_state);
  8419. for (n = 0; n < automaton_states.length (); n++)
  8420. {
  8421. state_t s = automaton_states[n];
  8422. for (arc = first_out_arc (s);
  8423. arc != NULL;
  8424. arc = next_out_arc (arc))
  8425. if (arc->to_state != s)
  8426. {
  8427. gcc_assert (arc->insn->first_insn_with_same_reservs);
  8428. for (ainsn = arc->insn;
  8429. ainsn != NULL;
  8430. ainsn = ainsn->next_same_reservs_insn)
  8431. ainsn->important_p = TRUE;
  8432. }
  8433. }
  8434. }
  8435. automaton_states.release ();
  8436. /* Create automata sets for the insns. */
  8437. for (i = 0; i < description->decls_num; i++)
  8438. {
  8439. decl = description->decls [i];
  8440. if (decl->mode == dm_insn_reserv)
  8441. {
  8442. automata_list_start ();
  8443. for (automaton = description->first_automaton;
  8444. automaton != NULL;
  8445. automaton = automaton->next_automaton)
  8446. for (ainsn = automaton->ainsn_list;
  8447. ainsn != NULL;
  8448. ainsn = ainsn->next_ainsn)
  8449. if (ainsn->important_p
  8450. && ainsn->insn_reserv_decl == DECL_INSN_RESERV (decl))
  8451. {
  8452. automata_list_add (automaton);
  8453. break;
  8454. }
  8455. DECL_INSN_RESERV (decl)->important_automata_list
  8456. = automata_list_finish ();
  8457. }
  8458. }
  8459. }
  8460. /* The following is top level function to generate automat(a,on) for
  8461. fast recognition of pipeline hazards. */
  8462. static void
  8463. expand_automata (void)
  8464. {
  8465. int i;
  8466. description = XCREATENODEVAR (struct description,
  8467. sizeof (struct description)
  8468. /* Two entries for special insns. */
  8469. + sizeof (decl_t) * (decls.length () + 1));
  8470. description->decls_num = decls.length ();
  8471. description->normal_decls_num = description->decls_num;
  8472. description->query_units_num = 0;
  8473. for (i = 0; i < description->decls_num; i++)
  8474. {
  8475. description->decls [i] = decls[i];
  8476. if (description->decls [i]->mode == dm_unit
  8477. && DECL_UNIT (description->decls [i])->query_p)
  8478. DECL_UNIT (description->decls [i])->query_num
  8479. = description->query_units_num++;
  8480. }
  8481. all_time = create_ticker ();
  8482. check_time = create_ticker ();
  8483. if (progress_flag)
  8484. fprintf (stderr, "Check description...");
  8485. check_all_description ();
  8486. if (progress_flag)
  8487. fprintf (stderr, "done\n");
  8488. ticker_off (&check_time);
  8489. generation_time = create_ticker ();
  8490. if (!have_error)
  8491. {
  8492. transform_insn_regexps ();
  8493. check_unit_distributions_to_automata ();
  8494. }
  8495. if (!have_error)
  8496. {
  8497. generate ();
  8498. check_automata_insn_issues ();
  8499. }
  8500. if (!have_error)
  8501. {
  8502. form_important_insn_automata_lists ();
  8503. }
  8504. ticker_off (&generation_time);
  8505. }
  8506. /* The following is top level function to output PHR and to finish
  8507. work with pipeline description translator. */
  8508. static void
  8509. write_automata (void)
  8510. {
  8511. output_time = create_ticker ();
  8512. if (progress_flag)
  8513. fprintf (stderr, "Forming and outputting automata tables...");
  8514. output_tables ();
  8515. if (progress_flag)
  8516. {
  8517. fprintf (stderr, "done\n");
  8518. fprintf (stderr, "Output functions to work with automata...");
  8519. }
  8520. output_chip_definitions ();
  8521. output_max_insn_queue_index_def ();
  8522. output_internal_min_issue_delay_func ();
  8523. output_internal_trans_func ();
  8524. /* Cache of insn dfa codes: */
  8525. fprintf (output_file, "\nstatic int *%s;\n", DFA_INSN_CODES_VARIABLE_NAME);
  8526. fprintf (output_file, "\nstatic int %s;\n\n",
  8527. DFA_INSN_CODES_LENGTH_VARIABLE_NAME);
  8528. output_dfa_insn_code_func ();
  8529. output_trans_func ();
  8530. output_min_issue_delay_func ();
  8531. output_internal_dead_lock_func ();
  8532. output_dead_lock_func ();
  8533. output_size_func ();
  8534. output_internal_reset_func ();
  8535. output_reset_func ();
  8536. output_min_insn_conflict_delay_func ();
  8537. output_default_latencies ();
  8538. output_internal_insn_latency_func ();
  8539. output_insn_latency_func ();
  8540. output_internal_maximal_insn_latency_func ();
  8541. output_maximal_insn_latency_func ();
  8542. output_print_reservation_func ();
  8543. /* Output function get_cpu_unit_code. */
  8544. fprintf (output_file, "\n#if %s\n\n", CPU_UNITS_QUERY_MACRO_NAME);
  8545. output_get_cpu_unit_code_func ();
  8546. output_cpu_unit_reservation_p ();
  8547. output_insn_has_dfa_reservation_p ();
  8548. fprintf (output_file, "\n#endif /* #if %s */\n\n",
  8549. CPU_UNITS_QUERY_MACRO_NAME);
  8550. output_dfa_clean_insn_cache_func ();
  8551. output_dfa_start_func ();
  8552. output_dfa_finish_func ();
  8553. if (progress_flag)
  8554. fprintf (stderr, "done\n");
  8555. if (v_flag)
  8556. {
  8557. output_description_file = fopen (output_description_file_name, "w");
  8558. if (output_description_file == NULL)
  8559. {
  8560. perror (output_description_file_name);
  8561. exit (FATAL_EXIT_CODE);
  8562. }
  8563. if (progress_flag)
  8564. fprintf (stderr, "Output automata description...");
  8565. output_description ();
  8566. output_automaton_descriptions ();
  8567. if (progress_flag)
  8568. fprintf (stderr, "done\n");
  8569. output_statistics (output_description_file);
  8570. }
  8571. if (stats_flag)
  8572. output_statistics (stderr);
  8573. ticker_off (&output_time);
  8574. if (time_flag)
  8575. output_time_statistics (stderr);
  8576. finish_states ();
  8577. finish_arcs ();
  8578. finish_automata_lists ();
  8579. if (time_flag)
  8580. {
  8581. fprintf (stderr, "Summary:\n");
  8582. fprintf (stderr, " check time ");
  8583. print_active_time (stderr, check_time);
  8584. fprintf (stderr, ", generation time ");
  8585. print_active_time (stderr, generation_time);
  8586. fprintf (stderr, ", all time ");
  8587. print_active_time (stderr, all_time);
  8588. fprintf (stderr, "\n");
  8589. }
  8590. /* Finish all work. */
  8591. if (output_description_file != NULL)
  8592. {
  8593. fflush (output_description_file);
  8594. if (ferror (stdout) != 0)
  8595. fatal ("Error in writing DFA description file %s: %s",
  8596. output_description_file_name, xstrerror (errno));
  8597. fclose (output_description_file);
  8598. }
  8599. finish_automaton_decl_table ();
  8600. finish_insn_decl_table ();
  8601. finish_decl_table ();
  8602. obstack_free (&irp, NULL);
  8603. if (have_error && output_description_file != NULL)
  8604. remove (output_description_file_name);
  8605. }
  8606. int
  8607. main (int argc, char **argv)
  8608. {
  8609. rtx desc;
  8610. progname = "genautomata";
  8611. if (!init_rtx_reader_args_cb (argc, argv, parse_automata_opt))
  8612. return (FATAL_EXIT_CODE);
  8613. initiate_automaton_gen (argv);
  8614. while (1)
  8615. {
  8616. int lineno;
  8617. int insn_code_number;
  8618. desc = read_md_rtx (&lineno, &insn_code_number);
  8619. if (desc == NULL)
  8620. break;
  8621. switch (GET_CODE (desc))
  8622. {
  8623. case DEFINE_CPU_UNIT:
  8624. gen_cpu_unit (desc);
  8625. break;
  8626. case DEFINE_QUERY_CPU_UNIT:
  8627. gen_query_cpu_unit (desc);
  8628. break;
  8629. case DEFINE_BYPASS:
  8630. gen_bypass (desc);
  8631. break;
  8632. case EXCLUSION_SET:
  8633. gen_excl_set (desc);
  8634. break;
  8635. case PRESENCE_SET:
  8636. gen_presence_set (desc);
  8637. break;
  8638. case FINAL_PRESENCE_SET:
  8639. gen_final_presence_set (desc);
  8640. break;
  8641. case ABSENCE_SET:
  8642. gen_absence_set (desc);
  8643. break;
  8644. case FINAL_ABSENCE_SET:
  8645. gen_final_absence_set (desc);
  8646. break;
  8647. case DEFINE_AUTOMATON:
  8648. gen_automaton (desc);
  8649. break;
  8650. case AUTOMATA_OPTION:
  8651. gen_automata_option (desc);
  8652. break;
  8653. case DEFINE_RESERVATION:
  8654. gen_reserv (desc);
  8655. break;
  8656. case DEFINE_INSN_RESERVATION:
  8657. gen_insn_reserv (desc);
  8658. break;
  8659. default:
  8660. break;
  8661. }
  8662. }
  8663. if (have_error)
  8664. return FATAL_EXIT_CODE;
  8665. if (decls.length () > 0)
  8666. {
  8667. expand_automata ();
  8668. if (!have_error)
  8669. {
  8670. puts ("/* Generated automatically by the program `genautomata'\n"
  8671. " from the machine description file `md'. */\n\n"
  8672. "#include \"config.h\"\n"
  8673. "#include \"system.h\"\n"
  8674. "#include \"coretypes.h\"\n"
  8675. "#include \"tm.h\"\n"
  8676. "#include \"hash-set.h\"\n"
  8677. "#include \"machmode.h\"\n"
  8678. "#include \"vec.h\"\n"
  8679. "#include \"double-int.h\"\n"
  8680. "#include \"input.h\"\n"
  8681. "#include \"alias.h\"\n"
  8682. "#include \"symtab.h\"\n"
  8683. "#include \"wide-int.h\"\n"
  8684. "#include \"inchash.h\"\n"
  8685. "#include \"tree.h\"\n"
  8686. "#include \"varasm.h\"\n"
  8687. "#include \"stor-layout.h\"\n"
  8688. "#include \"calls.h\"\n"
  8689. "#include \"rtl.h\"\n"
  8690. "#include \"tm_p.h\"\n"
  8691. "#include \"insn-config.h\"\n"
  8692. "#include \"recog.h\"\n"
  8693. "#include \"regs.h\"\n"
  8694. "#include \"output.h\"\n"
  8695. "#include \"insn-attr.h\"\n"
  8696. "#include \"diagnostic-core.h\"\n"
  8697. "#include \"flags.h\"\n"
  8698. "#include \"function.h\"\n"
  8699. "#include \"emit-rtl.h\"\n");
  8700. /* FIXME: emit-rtl.h can go away once crtl is in rtl.h. */
  8701. write_automata ();
  8702. }
  8703. }
  8704. else
  8705. {
  8706. puts ("/* Generated automatically by the program `genautomata'\n"
  8707. " from the machine description file `md'. */\n\n"
  8708. "/* There is no automaton, but ISO C forbids empty\n"
  8709. " translation units, so include a header file with some\n"
  8710. " declarations, and its pre-requisite header file. */\n"
  8711. "#include \"config.h\"\n"
  8712. "#include \"system.h\"\n");
  8713. }
  8714. fflush (stdout);
  8715. return (ferror (stdout) != 0 || have_error
  8716. ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
  8717. }