3 * (C) Copyright Jul 27 1996, Edmond J. Breen.
5 * This code may be copied for personal, non-profit use only.
18 #define isgoto(C,i) (opcode(C,i) >= jmpu && opcode(C,i) <= jmpTptr)
21 int ninst; /* # of instructions */
22 int leader; /* block leader */
23 int nb; /* number of braches leading from block */
24 int *branch; /* branch leaders */
27 #define crt_block() (block_t*)calloc(sizeof(block_t),1)
29 #define addbranch(x,y,z) do{\
30 x = (int*)realloc(x,(y+1)*sizeof(int));\
34 static void freeblock(block_t * b, int nb)
43 static block_t initblock(code_t *c, int leader, int *visit)
52 for(i=leader;i<nextinst(c);++i) {
55 if(opcode(c,i) == eicreturn)
57 else if(isgoto(c,i)) {
58 /*printf("[%d:%d]\n",i,i+ivalcode(c,i));*/
59 addbranch(b.branch,b.nb,i+ivalcode(c,i));
60 if(opcode(c,i) != jmpu) {
61 /*printf("[%d:%d]\n",i,i+1);*/
62 addbranch(b.branch,b.nb,i+1);
65 } else if(opcode(c,i) == jmptab) {
66 struct {int n;val_t *loc;} *p;
69 addbranch(b.branch,b.nb,i + p->loc[0].ival);
71 addbranch(b.branch,b.nb,i + p->loc[j+1].ival);
75 if(leader == nextinst(c))
81 void EiC_peephole(code_t *C, int *visit)
85 for(i = 0; i < n; ++i)
87 j = i + ivalcode(C,i);
90 if(opcode(C,j) == jmpu || opcode(C,i) == opcode(C,j)) {
91 /*visit[i+ivalcode(C,i)]--;*/
92 ivalcode(C,i) += ivalcode(C,j);
98 int EiC_analyseCode(code_t *C)
100 /* returns the index to the last visited instruction */
101 block_t *block = NULL;
107 visit = calloc(sizeof(*visit),nextinst(C)+1);
108 block = realloc(block,(nb+1)*sizeof(*block));
109 block[nb++] = initblock(C,0,visit);
112 for(j=0;j<block[i].nb;++j) {
113 if(!visit[block[i].branch[j]]) {
114 block = realloc(block,(nb+1)*sizeof(*block));
115 block[nb++] = initblock(C,block[i].branch[j],visit);
117 visit[block[i].branch[j]]++;
122 for(i=0;i<=nextinst(C);)
125 else if(i < nextinst(C) && instline(C,i)) {
126 EiC_warningerror("Unreachable code at line %d",instline(C,i));
127 for(;i<nextinst(C) && !visit[i];i++)
132 EiC_peephole(C,visit);
135 for(i=0;i<nextinst(C);++i)
137 setopcode(C,i,empty);
148 int EiC_checkPeepHole(token_t *e1,int op)
151 * A simple arithmetic optimizer:
152 * do not add or subtract 0
153 * and do not multiply or divide by 1
156 if (isconst(e1->Type)) {
157 if (op == '+' || op == '-')
158 switch (EiC_gettype(e1->Type)) {
159 CASE_INT: CASE_UINT:v = e1->Val.ival == 0;
161 CASE_LONG: CASE_ULONG:v = e1->Val.lval == 0;
163 CASE_FLOAT:v = e1->Val.dval == 0;
167 switch (EiC_gettype(e1->Type)) {
168 CASE_INT: CASE_UINT:v = e1->Val.ival == 1;
170 CASE_LONG: CASE_ULONG:v = e1->Val.lval == 1;
172 CASE_FLOAT:v = e1->Val.dval == 1;