123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803 |
- #include "limbo.h"
- #define bzero bbzero /* bsd name space pollution */
- /*
- (r, s) := f(); => r, s have def on same pc
- s = g(); => this def kills previous r def (and s def)
- solution: r has def pc, s has def pc+1 and next instruction has pc pc+2
- */
- #define BLEN (8*sizeof(ulong))
- #define BSHIFT 5 /* assumes ulong 4 */
- #define BMASK (BLEN-1)
- #define SIGN(n) (1<<(n-1))
- #define MSK(n) (SIGN(n)|(SIGN(n)-1))
- #define MASK(a, b) (MSK((b)-(a)+1)<<(a))
- #define isnilsrc(s) ((s)->start.line == 0 && (s)->stop.line == 0 && (s)->start.pos == 0 && (s)->stop.pos == 0)
- #define limbovar(d) ((d)->sym->name[0] != '.')
- #define structure(t) ((t)->kind == Tadt || (t)->kind == Ttuple)
- enum
- {
- Bclr,
- Band,
- Bandinv,
- Bstore,
- Bandrev,
- Bnoop,
- Bxor,
- Bor,
- Bnor,
- Bequiv,
- Binv,
- Bimpby,
- Brev,
- Bimp,
- Bnand,
- Bset,
- };
- enum
- {
- Suse = 1,
- Muse = 2,
- Duse = 4,
- Sdef = 8,
- Mdef = 16,
- Ddef = 32,
- Tuse1 = 64, /* fixed point temporary */
- Tuse2 = 128, /* fixed point temporary */
- Mduse = 256, /* D used if M nil */
- None = 0,
- Unop = Suse|Ddef,
- Cunop = Muse|Ddef,
- Threop = Suse|Muse|Ddef,
- Binop = Suse|Muse|Ddef|Mduse,
- Mbinop = Suse|Mdef|Duse, /* strange */
- Abinop=Suse|Duse|Ddef,
- Mabinop = Suse|Muse|Duse|Ddef,
- Use1 = Suse,
- Use2 = Suse|Duse,
- Use3 = Suse|Muse|Duse,
- };
- enum
- {
- Sshift = 10,
- Mshift = 5,
- Dshift = 0,
- };
- #define S(x) ((x)<<Sshift)
- #define M(x) ((x)<<Mshift)
- #define D(x) ((x)<<Dshift)
- #define SS(x) (((x)>>Sshift)&0x1f)
- #define SM(x) (((x)>>Mshift)&0x1f)
- #define SD(x) (((x)>>Dshift)&0x1f)
- enum
- {
- I = 0, /* ignore */
- B = 1, /* byte */
- W = 4, /* int */
- P = 4, /* pointer */
- A = 4, /* array */
- C = 4, /* string */
- X = 4, /* fixed */
- R = 4, /* float */
- L = 8, /* big */
- F = 8, /* real */
- Sh = 2, /* short */
- Pc = 4, /* pc */
- Mp = 16, /* memory */
- Bop2 = S(B)|D(B),
- Bop = S(B)|M(B)|D(B),
- Bopb = S(B)|M(B)|D(Pc),
- Wop2 = S(W)|D(W),
- Wop = S(W)|M(W)|D(W),
- Wopb = S(W)|M(W)|D(Pc),
- Lop2 = S(L)|D(L),
- Lop = S(L)|M(L)|D(L),
- Lopb = S(L)|M(L)|D(Pc),
- Cop2 = Wop2,
- Cop = Wop,
- Copb = Wopb,
- Fop2 = Lop2,
- Fop = Lop,
- Fopb = Lopb,
- Xop = Wop,
- };
- typedef struct Array Array;
- typedef struct Bits Bits;
- typedef struct Blist Blist;
- typedef struct Block Block;
- typedef struct Idlist Idlist;
- typedef struct Optab Optab;
- struct Array
- {
- int n;
- int m;
- Block **a;
- };
- struct Bits
- {
- int n;
- ulong *b;
- };
- struct Blist
- {
- Block *block;
- Blist *next;
- };
- struct Block
- {
- int dfn;
- int flags;
- Inst *first;
- Inst *last;
- Block *prev;
- Block *next;
- Blist *pred;
- Blist *succ;
- Bits kill;
- Bits gen;
- Bits in;
- Bits out;
- };
- struct Idlist
- {
- int id;
- Idlist *next;
- };
- struct Optab
- {
- short flags;
- short size;
- };
- Block zblock;
- Decl *regdecls;
- Idlist *frelist;
- Idlist *deflist;
- Idlist *uselist;
- static void
- addlist(Idlist **hd, int id)
- {
- Idlist *il;
- if(frelist == nil)
- il = (Idlist*)malloc(sizeof(Idlist));
- else{
- il = frelist;
- frelist = frelist->next;
- }
- il->id = id;
- il->next = *hd;
- *hd = il;
- }
- static void
- freelist(Idlist **hd)
- {
- Idlist *il;
- for(il = *hd; il != nil && il->next != nil; il = il->next)
- ;
- if(il != nil){
- il->next = frelist;
- frelist = *hd;
- *hd = nil;
- }
- }
-
- Optab opflags[] = {
- /* INOP */ None, 0,
- /* IALT */ Unop, S(Mp)|D(W),
- /* INBALT */ Unop, S(Mp)|D(W),
- /* IGOTO */ Use2, S(W)|D(I),
- /* ICALL */ Use2, S(P)|D(Pc),
- /* IFRAME */ Unop, S(W)|D(P),
- /* ISPAWN */ Use2, S(P)|D(Pc),
- /* IRUNT */ None, 0,
- /* ILOAD */ Threop, S(C)|M(P)|D(P),
- /* IMCALL */ Use3, S(P)|M(W)|D(P),
- /* IMSPAWN */ Use3, S(P)|M(W)|D(P),
- /* IMFRAME */ Threop, S(P)|M(W)|D(P),
- /* IRET */ None, 0,
- /* IJMP */ Duse, D(Pc),
- /* ICASE */ Use2, S(W)|D(I),
- /* IEXIT */ None, 0,
- /* INEW */ Unop, S(W)|D(P),
- /* INEWA */ Threop, S(W)|M(W)|D(P),
- /* INEWCB */ Cunop, M(W)|D(P),
- /* INEWCW */ Cunop, M(W)|D(P),
- /* INEWCF */ Cunop, M(W)|D(P),
- /* INEWCP */ Cunop, M(W)|D(P),
- /* INEWCM */ Threop, S(W)|M(W)|D(P),
- /* INEWCMP */ Threop, S(W)|M(W)|D(P),
- /* ISEND */ Use2, S(Mp)|D(P),
- /* IRECV */ Unop, S(P)|D(Mp),
- /* ICONSB */ Abinop, S(B)|D(P),
- /* ICONSW */ Abinop, S(W)|D(P),
- /* ICONSP */ Abinop, S(P)|D(P),
- /* ICONSF */ Abinop, S(F)|D(P),
- /* ICONSM */ Mabinop, S(Mp)|M(W)|D(P),
- /* ICONSMP */ Mabinop, S(Mp)|M(W)|D(P),
- /* IHEADB */ Unop, S(P)|D(B),
- /* IHEADW */ Unop, S(P)|D(W),
- /* IHEADP */ Unop, S(P)|D(P),
- /* IHEADF */ Unop, S(P)|D(F),
- /* IHEADM */ Threop, S(P)|M(W)|D(Mp),
- /* IHEADMP */ Threop, S(P)|M(W)|D(Mp),
- /* ITAIL */ Unop, S(P)|D(P),
- /* ILEA */ Ddef, S(Mp)|D(P), /* S done specially cos of ALT */
- /* IINDX */ Mbinop, S(P)|M(P)|D(W),
- /* IMOVP */ Unop, S(P)|D(P),
- /* IMOVM */ Threop, S(Mp)|M(W)|D(Mp),
- /* IMOVMP */ Threop, S(Mp)|M(W)|D(Mp),
- /* IMOVB */ Unop, Bop2,
- /* IMOVW */ Unop, Wop2,
- /* IMOVF */ Unop, Fop2,
- /* ICVTBW */ Unop, S(B)|D(W),
- /* ICVTWB */ Unop, S(W)|D(B),
- /* ICVTFW */ Unop, S(F)|D(W),
- /* ICVTWF */ Unop, S(W)|D(F),
- /* ICVTCA */ Unop, S(C)|D(A),
- /* ICVTAC */ Unop, S(A)|D(C),
- /* ICVTWC */ Unop, S(W)|D(C),
- /* ICVTCW */ Unop, S(C)|D(W),
- /* ICVTFC */ Unop, S(F)|D(C),
- /* ICVTCF */ Unop, S(C)|D(F),
- /* IADDB */ Binop, Bop,
- /* IADDW */ Binop, Wop,
- /* IADDF */ Binop, Fop,
- /* ISUBB */ Binop, Bop,
- /* ISUBW */ Binop, Wop,
- /* ISUBF */ Binop, Fop,
- /* IMULB */ Binop, Bop,
- /* IMULW */ Binop, Wop,
- /* IMULF */ Binop, Fop,
- /* IDIVB */ Binop, Bop,
- /* IDIVW */ Binop, Wop,
- /* IDIVF */ Binop, Fop,
- /* IMODW */ Binop, Wop,
- /* IMODB */ Binop, Bop,
- /* IANDB */ Binop, Bop,
- /* IANDW */ Binop, Wop,
- /* IORB */ Binop, Bop,
- /* IORW */ Binop, Wop,
- /* IXORB */ Binop, Bop,
- /* IXORW */ Binop, Wop,
- /* ISHLB */ Binop, S(W)|M(B)|D(B),
- /* ISHLW */ Binop, Wop,
- /* ISHRB */ Binop, S(W)|M(B)|D(B),
- /* ISHRW */ Binop, Wop,
- /* IINSC */ Mabinop, S(W)|M(W)|D(C),
- /* IINDC */ Threop, S(C)|M(W)|D(W),
- /* IADDC */ Binop, Cop,
- /* ILENC */ Unop, S(C)|D(W),
- /* ILENA */ Unop, S(A)|D(W),
- /* ILENL */ Unop, S(P)|D(W),
- /* IBEQB */ Use3, Bopb,
- /* IBNEB */ Use3, Bopb,
- /* IBLTB */ Use3, Bopb,
- /* IBLEB */ Use3, Bopb,
- /* IBGTB */ Use3, Bopb,
- /* IBGEB */ Use3, Bopb,
- /* IBEQW */ Use3, Wopb,
- /* IBNEW */ Use3, Wopb,
- /* IBLTW */ Use3, Wopb,
- /* IBLEW */ Use3, Wopb,
- /* IBGTW */ Use3, Wopb,
- /* IBGEW */ Use3, Wopb,
- /* IBEQF */ Use3, Fopb,
- /* IBNEF */ Use3, Fopb,
- /* IBLTF */ Use3, Fopb,
- /* IBLEF */ Use3, Fopb,
- /* IBGTF */ Use3, Fopb,
- /* IBGEF */ Use3, Fopb,
- /* IBEQC */ Use3, Copb,
- /* IBNEC */ Use3, Copb,
- /* IBLTC */ Use3, Copb,
- /* IBLEC */ Use3, Copb,
- /* IBGTC */ Use3, Copb,
- /* IBGEC */ Use3, Copb,
- /* ISLICEA */ Mabinop, S(W)|M(W)|D(P),
- /* ISLICELA */ Use3, S(P)|M(W)|D(P),
- /* ISLICEC */ Mabinop, S(W)|M(W)|D(C),
- /* IINDW */ Mbinop, S(P)|M(P)|D(W),
- /* IINDF */ Mbinop, S(P)|M(P)|D(W),
- /* IINDB */ Mbinop, S(P)|M(P)|D(W),
- /* INEGF */ Unop, Fop2,
- /* IMOVL */ Unop, Lop2,
- /* IADDL */ Binop, Lop,
- /* ISUBL */ Binop, Lop,
- /* IDIVL */ Binop, Lop,
- /* IMODL */ Binop, Lop,
- /* IMULL */ Binop, Lop,
- /* IANDL */ Binop, Lop,
- /* IORL */ Binop, Lop,
- /* IXORL */ Binop, Lop,
- /* ISHLL */ Binop, S(W)|M(L)|D(L),
- /* ISHRL */ Binop, S(W)|M(L)|D(L),
- /* IBNEL */ Use3, Lopb,
- /* IBLTL */ Use3, Lopb,
- /* IBLEL */ Use3, Lopb,
- /* IBGTL */ Use3, Lopb,
- /* IBGEL */ Use3, Lopb,
- /* IBEQL */ Use3, Lopb,
- /* ICVTLF */ Unop, S(L)|D(F),
- /* ICVTFL */ Unop, S(F)|D(L),
- /* ICVTLW */ Unop, S(L)|D(W),
- /* ICVTWL */ Unop, S(W)|D(L),
- /* ICVTLC */ Unop, S(L)|D(C),
- /* ICVTCL */ Unop, S(C)|D(L),
- /* IHEADL */ Unop, S(P)|D(L),
- /* ICONSL */ Abinop, S(L)|D(P),
- /* INEWCL */ Cunop, M(W)|D(P),
- /* ICASEC */ Use2, S(C)|D(I),
- /* IINDL */ Mbinop, S(P)|M(P)|D(W),
- /* IMOVPC */ Unop, S(W)|D(P),
- /* ITCMP */ Use2, S(P)|D(P),
- /* IMNEWZ */ Threop, S(P)|M(W)|D(P),
- /* ICVTRF */ Unop, S(R)|D(F),
- /* ICVTFR */ Unop, S(F)|D(R),
- /* ICVTWS */ Unop, S(W)|D(Sh),
- /* ICVTSW */ Unop, S(Sh)|D(W),
- /* ILSRW */ Binop, Wop,
- /* ILSRL */ Binop, S(W)|M(L)|D(L),
- /* IECLR */ None, 0,
- /* INEWZ */ Unop, S(W)|D(P),
- /* INEWAZ */ Threop, S(W)|M(W)|D(P),
- /* IRAISE */ Use1, S(P),
- /* ICASEL */ Use2, S(L)|D(I),
- /* IMULX */ Binop|Tuse2, Xop,
- /* IDIVX */ Binop|Tuse2, Xop,
- /* ICVTXX */ Threop, Xop,
- /* IMULX0 */ Binop|Tuse1|Tuse2, Xop,
- /* IDIVX0 */ Binop|Tuse1|Tuse2, Xop,
- /* ICVTXX0 */ Threop|Tuse1, Xop,
- /* IMULX1 */ Binop|Tuse1|Tuse2, Xop,
- /* IDIVX1 */ Binop|Tuse1|Tuse2, Xop,
- /* ICVTXX1 */ Threop|Tuse1, Xop,
- /* ICVTFX */ Threop, S(F)|M(F)|D(X),
- /* ICVTXF */ Threop, S(X)|M(F)|D(F),
- /* IEXPW */ Binop, S(W)|M(W)|D(W),
- /* IEXPL */ Binop, S(W)|M(L)|D(L),
- /* IEXPF */ Binop, S(W)|M(F)|D(F),
- /* ISELF */ Ddef, D(P),
- /* IEXC */ None, 0,
- /* IEXC0 */ None, 0,
- /* INOOP */ None, 0,
- };
- /*
- static int
- pop(int i)
- {
- i = (i & 0x55555555) + ((i>>1) & 0x55555555);
- i = (i & 0x33333333) + ((i>>2) & 0x33333333);
- i = (i & 0x0F0F0F0F) + ((i>>4) & 0x0F0F0F0F);
- i = (i & 0x00FF00FF) + ((i>>8) & 0x00FF00FF);
- i = (i & 0x0000FFFF) + ((i>>16) & 0x0000FFFF);
- return i;
- }
- */
- static int
- bitc(uint x)
- {
- uint n;
- n = (x>>1)&0x77777777;
- x -= n;
- n = (n>>1)&0x77777777;
- x -= n;
- n = (n>>1)&0x77777777;
- x -= n;
- x = (x+(x>>4))&0x0f0f0f0f;
- x *= 0x01010101;
- return x>>24;
- }
- /*
- static int
- top(uint x)
- {
- int i;
- for(i = -1; x; i++)
- x >>= 1;
- return i;
- }
- */
- static int
- topb(uint x)
- {
- int i;
- if(x == 0)
- return -1;
- i = 0;
- if(x&0xffff0000){
- i |= 16;
- x >>= 16;
- }
- if(x&0xff00){
- i |= 8;
- x >>= 8;
- }
- if(x&0xf0){
- i |= 4;
- x >>= 4;
- }
- if(x&0xc){
- i |= 2;
- x >>= 2;
- }
- if(x&0x2)
- i |= 1;
- return i;
- }
- /*
- static int
- lowb(uint x)
- {
- int i;
- if(x == 0)
- return -1;
- for(i = BLEN; x; i--)
- x <<= 1;
- return i;
- }
- */
- static int
- lowb(uint x)
- {
- int i;
- if(x == 0)
- return -1;
- i = 0;
- if((x&0xffff) == 0){
- i |= 16;
- x >>= 16;
- }
- if((x&0xff) == 0){
- i |= 8;
- x >>= 8;
- }
- if((x&0xf) == 0){
- i |= 4;
- x >>= 4;
- }
- if((x&0x3) == 0){
- i |= 2;
- x >>= 2;
- }
- return i+1-(x&1);
- }
-
- static void
- pbit(int x, int n)
- {
- int i, m;
- m = 1;
- for(i = 0; i < BLEN; i++){
- if(x&m)
- print("%d ", i+n);
- m <<= 1;
- }
- }
- static ulong
- bop(int o, ulong s, ulong d)
- {
- switch(o){
- case Bclr: return 0;
- case Band: return s & d;
- case Bandinv: return s & ~d;
- case Bstore: return s;
- case Bandrev: return ~s & d;
- case Bnoop: return d;
- case Bxor: return s ^ d;
- case Bor: return s | d;
- case Bnor: return ~(s | d);
- case Bequiv: return ~(s ^ d);
- case Binv: return ~d;
- case Bimpby: return s | ~d;
- case Brev: return ~s;
- case Bimp: return ~s | d;
- case Bnand: return ~(s & d);
- case Bset: return 0xffffffff;
- }
- return 0;
- }
- static Bits
- bnew(int n, int bits)
- {
- Bits b;
- if(bits)
- b.n = (n+BLEN-1)>>BSHIFT;
- else
- b.n = n;
- b.b = allocmem(b.n*sizeof(ulong));
- memset(b.b, 0, b.n*sizeof(ulong));
- return b;
- }
- static void
- bfree(Bits b)
- {
- free(b.b);
- }
- static void
- bset(Bits b, int n)
- {
- b.b[n>>BSHIFT] |= 1<<(n&BMASK);
- }
- static void
- bclr(Bits b, int n)
- {
- b.b[n>>BSHIFT] &= ~(1<<(n&BMASK));
- }
- static int
- bmem(Bits b, int n)
- {
- return b.b[n>>BSHIFT] & (1<<(n&BMASK));
- }
- static void
- bsets(Bits b, int m, int n)
- {
- int i, c1, c2;
- c1 = m>>BSHIFT;
- c2 = n>>BSHIFT;
- m &= BMASK;
- n &= BMASK;
- if(c1 == c2){
- b.b[c1] |= MASK(m, n);
- return;
- }
- for(i = c1+1; i < c2; i++)
- b.b[i] = 0xffffffff;
- b.b[c1] |= MASK(m, BLEN-1);
- b.b[c2] |= MASK(0, n);
- }
- static void
- bclrs(Bits b, int m, int n)
- {
- int i, c1, c2;
- if(n < 0)
- n = (b.n<<BSHIFT)-1;
- c1 = m>>BSHIFT;
- c2 = n>>BSHIFT;
- m &= BMASK;
- n &= BMASK;
- if(c1 == c2){
- b.b[c1] &= ~MASK(m, n);
- return;
- }
- for(i = c1+1; i < c2; i++)
- b.b[i] = 0;
- b.b[c1] &= ~MASK(m, BLEN-1);
- b.b[c2] &= ~MASK(0, n);
- }
-
- /* b = a op b */
- static Bits
- boper(int o, Bits a, Bits b)
- {
- int i, n;
- n = a.n;
- if(b.n != n)
- fatal("boper %d %d %d", o, a.n, b.n);
- for(i = 0; i < n; i++)
- b.b[i] = bop(o, a.b[i], b.b[i]);
- return b;
- }
- static int
- beq(Bits a, Bits b)
- {
- int i, n;
- n = a.n;
- for(i = 0; i < n; i++)
- if(a.b[i] != b.b[i])
- return 0;
- return 1;
- }
- static int
- bzero(Bits b)
- {
- int i, n;
- n = b.n;
- for(i = 0; i < n; i++)
- if(b.b[i] != 0)
- return 0;
- return 1;
- }
- static int
- bitcnt(Bits b)
- {
- int i, m, n;
- m = b.n;
- n = 0;
- for(i = 0; i < m; i++)
- n += bitc(b.b[i]);
- return n;
- }
- static int
- topbit(Bits b)
- {
- int i, n;
- n = b.n;
- for(i = n-1; i >= 0; i--)
- if(b.b[i] != 0)
- return (i<<BSHIFT)+topb(b.b[i]);
- return -1;
- }
- static int
- lowbit(Bits b)
- {
- int i, n;
- n = b.n;
- for(i = 0; i < n; i++)
- if(b.b[i] != 0)
- return (i<<BSHIFT)+lowb(b.b[i]);
- return -1;
- }
- static void
- pbits(Bits b)
- {
- int i, n;
- n = b.n;
- for(i = 0; i < n; i++)
- pbit(b.b[i], i<<BSHIFT);
- }
- static char*
- decname(Decl *d)
- {
- if(d->sym == nil)
- return "<nil>";
- return d->sym->name;
- }
- static void
- warning(Inst *i, char *s, Decl *d, Decl *sd)
- {
- int n;
- char *f;
- Decl *ds;
- n = 0;
- for(ds = sd; ds != nil; ds = ds->next)
- if(ds->link == d)
- n += strlen(ds->sym->name)+1;
- if(n == 0){
- warn(i->src.start, "%s: %s", d->sym->name, s);
- return;
- }
- n += strlen(d->sym->name);
- f = malloc(n+1);
- strcpy(f, d->sym->name);
- for(ds = sd; ds != nil; ds = ds->next){
- if(ds->link == d){
- strcat(f, "/");
- strcat(f, ds->sym->name);
- }
- }
- warn(i->src.start, "%s: %s", f, s);
- free(f);
- }
- static int
- inspc(Inst *in)
- {
- int n;
- Inst *i;
- n = 0;
- for(i = in; i != nil; i = i->next)
- i->pc = n++;
- return n;
- }
- static Inst*
- pc2i(Block *b, int pc)
- {
- Inst *i;
- for( ; b != nil; b = b->next){
- if(pc > b->last->pc)
- continue;
- for(i = b->first; ; i = i->next){
- if(i->pc == pc)
- return i;
- if(i == b->last)
- fatal("pc2i a");
- }
- }
- fatal("pc2i b");
- return nil;
- }
- static void
- padr(int am, Addr *a, Inst *br)
- {
- long reg;
- if(br != nil){
- print("$%ld", br->pc);
- return;
- }
- reg = a->reg;
- if(a->decl != nil && am != Adesc)
- reg += a->decl->offset;
- switch(am){
- case Anone:
- print("-");
- break;
- case Aimm:
- case Apc:
- case Adesc:
- print("$%ld", a->offset);
- break;
- case Aoff:
- print("$%ld", a->decl->iface->offset);
- break;
- case Anoff:
- print("-$%ld", a->decl->iface->offset);
- break;
- case Afp:
- print("%ld(fp)", reg);
- break;
- case Afpind:
- print("%ld(%ld(fp))", a->offset, reg);
- break;
- case Amp:
- print("%ld(mp)", reg);
- break;
- case Ampind:
- print("%ld(%ld(mp))", a->offset, reg);
- break;
- case Aldt:
- print("$%ld", reg);
- break;
- case Aerr:
- default:
- print("%ld(%ld(?%d?))", a->offset, reg, am);
- break;
- }
- }
- static void
- pins(Inst *i)
- {
- /* print("%L %ld ", i->src.start, i->pc); */
- print(" %ld ", i->pc);
- if(i->op < MAXDIS)
- print("%s", instname[i->op]);
- else
- print("noop");
- print(" ");
- padr(i->sm, &i->s, nil);
- print(", ");
- padr(i->mm, &i->m, nil);
- print(", ");
- padr(i->dm, &i->d, i->branch);
- print("\n");
- }
- static void
- blfree(Blist *bl)
- {
- Blist *nbl;
- for( ; bl != nil; bl = nbl){
- nbl = bl->next;
- free(bl);
- }
- }
- static void
- freebits(Bits *bs, int nv)
- {
- int i;
- for(i = 0; i < nv; i++)
- bfree(bs[i]);
- free(bs);
- }
- static void
- freeblks(Block *b)
- {
- Block *nb;
- for( ; b != nil; b = nb){
- blfree(b->pred);
- blfree(b->succ);
- bfree(b->kill);
- bfree(b->gen);
- bfree(b->in);
- bfree(b->out);
- nb = b->next;
- free(b);
- }
- }
- static int
- len(Decl *d)
- {
- int n;
- n = 0;
- for( ; d != nil; d = d->next)
- n++;
- return n;
- }
- static Bits*
- allocbits(int nv, int npc)
- {
- int i;
- Bits *defs;
- defs = (Bits*)allocmem(nv*sizeof(Bits));
- for(i = 0; i < nv; i++)
- defs[i] = bnew(npc, 1);
- return defs;
- }
- static int
- bitcount(Bits *bs, int nv)
- {
- int i, n;
- n = 0;
- for(i = 0; i < nv; i++)
- n += bitcnt(bs[i]);
- return n;
- }
- static Block*
- mkblock(Inst *i)
- {
- Block *b;
- b = allocmem(sizeof(Block));
- *b = zblock;
- b->first = b->last = i;
- return b;
- }
- static Blist*
- mkblist(Block *b, Blist *nbl)
- {
- Blist *bl;
- bl = allocmem(sizeof(Blist));
- bl->block = b;
- bl->next = nbl;
- return bl;
- }
- static void
- leader(Inst *i, Array *ab)
- {
- int m, n;
- Block *b, **a;
- if(i != nil && i->pc == 0){
- if((n = ab->n) == (m = ab->m)){
- a = ab->a;
- ab->a = allocmem(2*m*sizeof(Block*));
- memcpy(ab->a, a, m*sizeof(Block*));
- ab->m = 2*m;
- free(a);
- }
- b = mkblock(i);
- b->dfn = n;
- ab->a[n] = b;
- i->pc = ab->n = n+1;
- }
- }
- static Block*
- findb(Inst *i, Array *ab)
- {
- if(i == nil)
- return nil;
- if(i->pc <= 0)
- fatal("pc <= 0 in findb");
- return ab->a[i->pc-1];
- }
- static int
- memb(Block *b, Blist *bl)
- {
- for( ; bl != nil; bl = bl->next)
- if(bl->block == b)
- return 1;
- return 0;
- }
- static int
- canfallthrough(Inst *i)
- {
- if(i == nil)
- return 0;
- switch(i->op){
- case IGOTO:
- case ICASE:
- case ICASEL:
- case ICASEC:
- case IRET:
- case IEXIT:
- case IRAISE:
- case IJMP:
- return 0;
- case INOOP:
- return i->branch != nil;
- }
- return 1;
- }
- static void
- predsucc(Block *b1, Block *b2)
- {
- if(b1 == nil || b2 == nil)
- return;
- if(!memb(b1, b2->pred))
- b2->pred = mkblist(b1, b2->pred);
- if(!memb(b2, b1->succ))
- b1->succ = mkblist(b2, b1->succ);
- }
-
- static Block*
- mkblocks(Inst *in, int *nb)
- {
- Inst *i;
- Block *b, *firstb, *lastb;
- Label *lab;
- Array *ab;
- int j, n;
- ab = allocmem(sizeof(Array));
- ab->n = 0;
- ab->m = 16;
- ab->a = allocmem(ab->m*sizeof(Block*));
- leader(in, ab);
- for(i = in; i != nil; i = i->next){
- switch(i->op){
- case IGOTO:
- case ICASE:
- case ICASEL:
- case ICASEC:
- case INOOP:
- if(i->op == INOOP && i->branch != nil){
- leader(i->branch, ab);
- leader(i->next, ab);
- break;
- }
- leader(i->d.decl->ty->cse->iwild, ab);
- lab = i->d.decl->ty->cse->labs;
- n = i->d.decl->ty->cse->nlab;
- for(j = 0; j < n; j++)
- leader(lab[j].inst, ab);
- leader(i->next, ab);
- break;
- case IRET:
- case IEXIT:
- case IRAISE:
- leader(i->next, ab);
- break;
- case IJMP:
- leader(i->branch, ab);
- leader(i->next, ab);
- break;
- default:
- if(i->branch != nil){
- leader(i->branch, ab);
- leader(i->next, ab);
- }
- break;
- }
- }
- firstb = lastb = mkblock(nil);
- for(i = in; i != nil; i = i->next){
- if(i->pc != 0){
- b = findb(i, ab);
- b->prev = lastb;
- lastb->next = b;
- if(canfallthrough(lastb->last))
- predsucc(lastb, b);
- lastb = b;
- }
- else
- lastb->last = i;
- switch(i->op){
- case IGOTO:
- case ICASE:
- case ICASEL:
- case ICASEC:
- case INOOP:
- if(i->op == INOOP && i->branch != nil){
- b = findb(i->next, ab);
- predsucc(lastb, b);
- b = findb(i->branch, ab);
- predsucc(lastb, b);
- break;
- }
- b = findb(i->d.decl->ty->cse->iwild, ab);
- predsucc(lastb, b);
- lab = i->d.decl->ty->cse->labs;
- n = i->d.decl->ty->cse->nlab;
- for(j = 0; j < n; j++){
- b = findb(lab[j].inst, ab);
- predsucc(lastb, b);
- }
- break;
- case IRET:
- case IEXIT:
- case IRAISE:
- break;
- case IJMP:
- b = findb(i->branch, ab);
- predsucc(lastb, b);
- break;
- default:
- if(i->branch != nil){
- b = findb(i->next, ab);
- predsucc(lastb, b);
- b = findb(i->branch, ab);
- predsucc(lastb, b);
- }
- break;
- }
- }
- *nb = ab->n;
- free(ab->a);
- free(ab);
- b = firstb->next;
- b->prev = nil;
- return b;
- }
- static int
- back(Block *b1, Block *b2)
- {
- return b1->dfn >= b2->dfn;
- }
- static void
- pblocks(Block *b, int nb)
- {
- Inst *i;
- Blist *bl;
- print("--------------------%d blocks--------------------\n", nb);
- print("------------------------------------------------\n");
- for( ; b != nil; b = b->next){
- print("dfn=%d\n", b->dfn);
- print(" pred ");
- for(bl = b->pred; bl != nil; bl = bl->next)
- print("%d%s ", bl->block->dfn, back(bl->block, b) ? "*" : "");
- print("\n");
- print(" succ ");
- for(bl = b->succ; bl != nil; bl = bl->next)
- print("%d%s ", bl->block->dfn, back(b, bl->block) ? "*" : "");
- print("\n");
- for(i = b->first; i != nil; i = i->next){
- // print(" %I\n", i);
- pins(i);
- if(i == b->last)
- break;
- }
- }
- print("------------------------------------------------\n");
- }
- static void
- ckblocks(Inst *in, Block *b, int nb)
- {
- int n;
- Block *lastb;
- if(b->first != in)
- fatal("A - %d", b->dfn);
- n = 0;
- lastb = nil;
- for( ; b != nil; b = b->next){
- n++;
- if(b->prev != lastb)
- fatal("a - %d\n", b->dfn);
- if(b->prev != nil && b->prev->next != b)
- fatal("b - %d\n", b->dfn);
- if(b->next != nil && b->next->prev != b)
- fatal("c - %d\n", b->dfn);
- if(b->prev != nil && b->prev->last->next != b->first)
- fatal("B - %d\n", b->dfn);
- if(b->next != nil && b->last->next != b->next->first)
- fatal("C - %d\n", b->dfn);
- if(b->next == nil && b->last->next != nil)
- fatal("D - %d\n", b->dfn);
- if(b->last->branch != nil && b->succ->block->first != b->last->branch)
- fatal("0 - %d\n", b->dfn);
- lastb = b;
- }
- if(n != nb)
- fatal("N - %d %d\n", n, nb);
- }
- static void
- dfs0(Block *b, int *n)
- {
- Block *s;
- Blist *bl;
- b->flags = 1;
- for(bl = b->succ; bl != nil; bl = bl->next){
- s = bl->block;
- if(s->flags == 0)
- dfs0(s, n);
- }
- b->dfn = --(*n);
- }
- static int
- dfs(Block *b, int nb)
- {
- int n, u;
- Block *b0;
- b0 = b;
- n = nb;
- dfs0(b0, &n);
- u = 0;
- for(b = b0; b != nil; b = b->next){
- if(b->flags == 0){ /* unreachable: see foldbranch */
- fatal("found unreachable code");
- u++;
- b->prev->next = b->next;
- if(b->next){
- b->next->prev = b->prev;
- b->prev->last->next = b->next->first;
- }
- else
- b->prev->last->next = nil;
- }
- b->flags = 0;
- }
- if(u){
- for(b = b0; b != nil; b = b->next)
- b->dfn -= u;
- }
- return nb-u;
- }
- static void
- loop0(Block *b)
- {
- Block *p;
- Blist *bl;
- b->flags = 1;
- for(bl = b->pred; bl != nil; bl = bl->next){
- p = bl->block;
- if(p->flags == 0)
- loop0(p);
- }
- }
- /* b1->b2 a back edge */
- static void
- loop(Block *b, Block *b1, Block *b2)
- {
- if(0 && debug['o'])
- print("back edge %d->%d\n", b1->dfn, b2->dfn);
- b2->flags = 1;
- if(b1->flags == 0)
- loop0(b1);
- if(0 && debug['o'])
- print(" loop ");
- for( ; b != nil; b = b->next){
- if(b->flags && 0 && debug['o'])
- print("%d ", b->dfn);
- b->flags = 0;
- }
- if(0 && debug['o'])
- print("\n");
- }
- static void
- loops(Block *b)
- {
- Block *b0;
- Blist *bl;
- b0 = b;
- for( ; b != nil; b = b->next){
- for(bl = b->succ; bl != nil; bl = bl->next){
- if(back(b, bl->block))
- loop(b0, b, bl->block);
- }
- }
- }
- static int
- imm(int m, Addr *a)
- {
- if(m == Aimm)
- return a->offset;
- fatal("bad immediate value");
- return -1;
- }
- static int
- desc(int m, Addr *a)
- {
- if(m == Adesc)
- return a->decl->desc->size;
- fatal("bad descriptor value");
- return -1;
- }
- static int
- fpoff(int m, Addr *a)
- {
- int off;
- Decl *d;
- if(m == Afp || m == Afpind){
- off = a->reg;
- if((d = a->decl) != nil)
- off += d->offset;
- return off;
- }
- return -1;
- }
- static int
- size(Inst *i)
- {
- switch(i->op){
- case ISEND:
- case IRECV:
- case IALT:
- case INBALT:
- case ILEA:
- return i->m.offset;
- case IMOVM:
- case IHEADM:
- case ICONSM:
- return imm(i->mm, &i->m);
- case IMOVMP:
- case IHEADMP:
- case ICONSMP:
- return desc(i->mm, &i->m);
- break;
- }
- fatal("bad op in size");
- return -1;
- }
- static Decl*
- mkdec(int o)
- {
- Decl *d;
- d = mkdecl(&nosrc, Dlocal, tint);
- d->offset = o;
- return d;
- }
- static void
- mkdecls(void)
- {
- regdecls = mkdec(REGRET*IBY2WD);
- regdecls->next = mkdec(STemp);
- regdecls->next->next = mkdec(DTemp);
- }
- static Decl*
- sharedecls(Decl *d)
- {
- Decl *ld;
- ld = d;
- for(d = d->next ; d != nil; d = d->next){
- if(d->offset <= ld->offset)
- break;
- ld = d;
- }
- return d;
- }
- static int
- finddec(int o, int s, Decl *vars, int *nv, Inst *i)
- {
- int m, n;
- Decl *d;
- n = 0;
- for(d = vars; d != nil; d = d->next){
- if(o >= d->offset && o < d->offset+d->ty->size){
- m = 1;
- while(o+s > d->offset+d->ty->size){
- m++;
- d = d->next;
- }
- *nv = m;
- return n;
- }
- n++;
- }
- // print("%d %d missing\n", o, s);
- pins(i);
- fatal("missing decl");
- return -1;
- }
- static void
- setud(Bits *b, int id, int n, int pc)
- {
- if(id < 0)
- return;
- while(--n >= 0)
- bset(b[id++], pc);
- }
- static void
- ud(Inst *i, Decl *vars, Bits *uses, Bits *defs)
- {
- ushort f;
- int id, j, nv, pc, sz, s, m, d, ss, sm, sd;
- Optab *t;
- Idlist *l;
- pc = i->pc;
- ss = 0;
- t = &opflags[i->op];
- f = t->flags;
- sz = t->size;
- s = fpoff(i->sm, &i->s);
- m = fpoff(i->mm, &i->m);
- d = fpoff(i->dm, &i->d);
- if(f&Mduse && i->mm == Anone)
- f |= Duse;
- if(s >= 0){
- if(i->sm == Afp){
- ss = SS(sz);
- if(ss == Mp)
- ss = size(i);
- }
- else
- ss = IBY2WD;
- id = finddec(s, ss, vars, &nv, i);
- if(f&Suse)
- setud(uses, id, nv, pc);
- if(f&Sdef){
- if(i->sm == Afp)
- setud(defs, id, nv, pc);
- else
- setud(uses, id, nv, pc);
- }
- }
- if(m >= 0){
- if(i->mm == Afp){
- sm = SM(sz);
- if(sm == Mp)
- sm = size(i);
- }
- else
- sm = IBY2WD;
- id = finddec(m, sm, vars, &nv, i);
- if(f&Muse)
- setud(uses, id, nv, pc);
- if(f&Mdef){
- if(i->mm == Afp)
- setud(defs, id, nv, pc);
- else
- setud(uses, id, nv, pc);
- }
- }
- if(d >= 0){
- if(i->dm == Afp){
- sd = SD(sz);
- if(sd == Mp)
- sd = size(i);
- }
- else
- sd = IBY2WD;
- id = finddec(d, sd, vars, &nv, i);
- if(f&Duse)
- setud(uses, id, nv, pc);
- if(f&Ddef){
- if(i->dm == Afp)
- setud(defs, id, nv, pc);
- else
- setud(uses, id, nv, pc);
- }
- }
- if(f&Tuse1){
- id = finddec(STemp, IBY2WD, vars, &nv, i);
- setud(uses, id, nv, pc);
- }
- if(f&Tuse2){
- id = finddec(DTemp, IBY2WD, vars, &nv, i);
- setud(uses, id, nv, pc);
- }
- if(i->op == ILEA){
- if(s >= 0){
- id = finddec(s, ss, vars, &nv, i);
- if(i->sm == Afp && i->m.reg == 0)
- setud(defs, id, nv, pc);
- else
- setud(uses, id, nv, pc);
- }
- }
- if(0)
- switch(i->op){
- case ILEA:
- if(s >= 0){
- id = finddec(s, ss, vars, &nv, i);
- if(id < 0)
- break;
- for(j = 0; j < nv; j++){
- if(i->sm == Afp && i->m.reg == 0)
- addlist(&deflist, id++);
- else
- addlist(&uselist, id++);
- }
- }
- break;
- case IALT:
- case INBALT:
- case ICALL:
- case IMCALL:
- for(l = deflist; l != nil; l = l->next){
- id = l->id;
- bset(defs[id], pc);
- }
- for(l = uselist; l != nil; l = l->next){
- id = l->id;
- bset(uses[id], pc);
- }
- freelist(&deflist);
- freelist(&uselist);
- break;
- }
- }
- static void
- usedef(Inst *in, Decl *vars, Bits *uses, Bits *defs)
- {
- Inst *i;
- for(i = in; i != nil; i = i->next)
- ud(i, vars, uses, defs);
- }
- static void
- pusedef(Bits *ud, int nv, Decl *d, char *s)
- {
- int i;
- print("%s\n", s);
- for(i = 0; i < nv; i++){
- if(!bzero(ud[i])){
- print("\t%s(%ld): ", decname(d), d->offset);
- pbits(ud[i]);
- print("\n");
- }
- d = d->next;
- }
- }
- static void
- dummydefs(Bits *defs, int nv, int npc)
- {
- int i;
- for(i = 0; i < nv; i++)
- bset(defs[i], npc++);
- }
- static void
- dogenkill(Block *b, Bits *defs, int nv)
- {
- int i, n, t;
- Bits v;
- n = defs[0].n;
- v = bnew(n, 0);
- for( ; b != nil; b = b->next){
- b->gen = bnew(n, 0);
- b->kill = bnew(n, 0);
- b->in = bnew(n, 0);
- b->out = bnew(n, 0);
- for(i = 0; i < nv; i++){
- boper(Bclr, v, v);
- bsets(v, b->first->pc, b->last->pc);
- boper(Band, defs[i], v);
- t = topbit(v);
- if(t >= 0)
- bset(b->gen, t);
- else
- continue;
- boper(Bclr, v, v);
- bsets(v, b->first->pc, b->last->pc);
- boper(Binv, v, v);
- boper(Band, defs[i], v);
- boper(Bor, v, b->kill);
- }
- }
- bfree(v);
- }
- static void
- udflow(Block *b, int nv, int npc)
- {
- int iter;
- Block *b0, *p;
- Blist *bl;
- Bits newin;
- b0 = b;
- for(b = b0; b != nil; b = b->next)
- boper(Bstore, b->gen, b->out);
- newin = bnew(b0->in.n, 0);
- iter = 1;
- while(iter){
- iter = 0;
- for(b = b0; b != nil; b = b->next){
- boper(Bclr, newin, newin);
- for(bl = b->pred; bl != nil; bl = bl->next){
- p = bl->block;
- boper(Bor, p->out, newin);
- }
- if(b == b0)
- bsets(newin, npc, npc+nv-1);
- if(!beq(b->in, newin))
- iter = 1;
- boper(Bstore, newin, b->in);
- boper(Bstore, b->in, b->out);
- boper(Bandrev, b->kill, b->out);
- boper(Bor, b->gen, b->out);
- }
- }
- bfree(newin);
- }
- static void
- pflows(Block *b)
- {
- for( ; b != nil; b = b->next){
- print("block %d\n", b->dfn);
- print(" gen: "); pbits(b->gen); print("\n");
- print(" kill: "); pbits(b->kill); print("\n");
- print(" in: "); pbits(b->in); print("\n");
- print(" out: "); pbits(b->out); print("\n");
- }
- }
- static int
- set(Decl *d)
- {
- if(d->store == Darg)
- return 1;
- if(d->sym == nil) /* || d->sym->name[0] == '.') */
- return 1;
- if(tattr[d->ty->kind].isptr || d->ty->kind == Texception)
- return 1;
- return 0;
- }
- static int
- used(Decl *d)
- {
- if(d->sym == nil ) /* || d->sym->name[0] == '.') */
- return 1;
- return 0;
- }
- static void
- udchain(Block *b, Decl *ds, int nv, int npc, Bits *defs, Bits *uses, Decl *sd)
- {
- int i, n, p, q;
- Bits d, u, dd, ud;
- Block *b0;
- Inst *in;
- b0 = b;
- n = defs[0].n;
- u = bnew(n, 0);
- d = bnew(n, 0);
- dd = bnew(n, 0);
- ud = bnew(n, 0);
- for(i = 0; i < nv; i++){
- boper(Bstore, defs[i], ud);
- bclr(ud, npc+i);
- for(b = b0 ; b != nil; b = b->next){
- boper(Bclr, u, u);
- bsets(u, b->first->pc, b->last->pc);
- boper(Band, uses[i], u);
- boper(Bclr, d, d);
- bsets(d, b->first->pc, b->last->pc);
- boper(Band, defs[i], d);
- for(;;){
- p = topbit(u);
- if(p < 0)
- break;
- bclr(u, p);
- bclrs(d, p, -1);
- q = topbit(d);
- if(q >= 0){
- bclr(ud, q);
- if(debug['o'])
- print("udc b=%d v=%d(%s/%ld) u=%d d=%d\n", b->dfn, i, decname(ds), ds->offset, p, q);
- }
- else{
- boper(Bstore, defs[i], dd);
- boper(Band, b->in, dd);
- boper(Bandrev, dd, ud);
- if(!bzero(dd)){
- if(debug['o']){
- print("udc b=%d v=%d(%s/%ld) u=%d d=", b->dfn, i, decname(ds), ds->offset, p);
- pbits(dd);
- print("\n");
- }
- if(bmem(dd, npc+i) && !set(ds))
- warning(pc2i(b0, p), "used and not set", ds, sd);
- }
- else
- fatal("no defs in udchain");
- }
- }
- }
- for(;;){
- p = topbit(ud);
- if(p < 0)
- break;
- bclr(ud, p);
- if(!used(ds)){
- in = pc2i(b0, p);
- if(isnilsrc(&in->src)) /* nilling code */
- in->op = INOOP; /* elim p from bitmaps ? */
- else if(limbovar(ds) && !structure(ds->ty))
- warning(in, "set and not used", ds, sd);
- }
- }
- ds = ds->next;
- }
- bfree(u);
- bfree(d);
- bfree(dd);
- bfree(ud);
- }
- static void
- ckflags(void)
- {
- int i, j, k, n;
- Optab *o;
- n = nelem(opflags);
- o = opflags;
- for(i = 0; i < n; i++){
- j = (o->flags&(Suse|Sdef)) != 0;
- k = SS(o->size) != 0;
- if(j != k){
- if(!(j == 0 && k == 1 && i == ILEA))
- fatal("S %ld %s\n", o-opflags, instname[i]);
- }
- j = (o->flags&(Muse|Mdef)) != 0;
- k = SM(o->size) != 0;
- if(j != k)
- fatal("M %ld %s\n", o-opflags, instname[i]);
- j = (o->flags&(Duse|Ddef)) != 0;
- k = SD(o->size) != 0;
- if(j != k){
- if(!(j == 1 && k == 0 && (i == IGOTO || i == ICASE || i == ICASEC || i == ICASEL)))
- fatal("D %ld %s\n", o-opflags, instname[i]);
- }
- o++;
- }
- }
- void
- optim(Inst *in, Decl *d)
- {
- int nb, npc, nv, nd, nu;
- Block *b;
- Bits *uses, *defs;
- Decl *sd;
- ckflags();
- if(debug['o'])
- print("************************************************\nfunction %s\n************************************************\n", d->sym->name);
- if(in == nil || errors > 0)
- return;
- d = d->ty->ids;
- if(regdecls == nil)
- mkdecls();
- regdecls->next->next->next = d;
- d = regdecls;
- sd = sharedecls(d);
- if(debug['o'])
- printdecls(d);
- b = mkblocks(in, &nb);
- ckblocks(in, b, nb);
- npc = inspc(in);
- nb = dfs(b, nb);
- if(debug['o'])
- pblocks(b, nb);
- loops(b);
- nv = len(d);
- uses = allocbits(nv, npc+nv);
- defs = allocbits(nv, npc+nv);
- dummydefs(defs, nv, npc);
- usedef(in, d, uses, defs);
- if(debug['o']){
- pusedef(uses, nv, d, "uses");
- pusedef(defs, nv, d, "defs");
- }
- nu = bitcount(uses, nv);
- nd = bitcount(defs, nv);
- dogenkill(b, defs, nv);
- udflow(b, nv, npc);
- if(debug['o'])
- pflows(b);
- udchain(b, d, nv, npc, defs, uses, sd);
- freeblks(b);
- freebits(uses, nv);
- freebits(defs, nv);
- if(debug['o'])
- print("nb=%d npc=%d nv=%d nd=%d nu=%d\n", nb, npc, nv, nd, nu);
- }
|