📄 optomizer.c
字号:
/* optomizer.c * * (C) Copyright Jul 27 1996, Edmond J. Breen. * ALL RIGHTS RESERVED. * This code may be copied for personal, non-profit use only. * */#include <stdio.h>#include <stdlib.h>#include <string.h>#include "MachSet.h"#include "global.h"#include "typesets.h"#include "error.h"#define isgoto(C,i) (opcode(C,i) >= jmpu && opcode(C,i) <= jmpTptr)typedef struct { int ninst; /* # of instructions */ int leader; /* block leader */ int nb; /* number of braches leading from block */ int *branch; /* branch leaders */}block_t;#define crt_block() (block_t*)calloc(sizeof(block_t),1)#define addbranch(x,y,z) do{\ x = (int*)realloc(x,(y+1)*sizeof(int));\ x[y++] = z;\ }while(0)static void freeblock(block_t * b, int nb){ int i; for(i =0;i<nb;++i) if(b[i].branch) free(b[i].branch); free(b);}static block_t initblock(code_t *c, int leader, int *visit){ int i; block_t b; b.leader = leader; b.branch = NULL; b.nb = 0; b.ninst = 0; for(i=leader;i<nextinst(c);++i) { visit[i]++; b.ninst++; if(opcode(c,i) == eicreturn) break; else if(isgoto(c,i)) { /*printf("[%d:%d]\n",i,i+ivalcode(c,i));*/ addbranch(b.branch,b.nb,i+ivalcode(c,i)); if(opcode(c,i) != jmpu) { /*printf("[%d:%d]\n",i,i+1);*/ addbranch(b.branch,b.nb,i+1); } break; } else if(opcode(c,i) == jmptab) { struct {int n;val_t *loc;} *p; int j; p = pvalcode(c,i); addbranch(b.branch,b.nb,i + p->loc[0].ival); for(j =1;j<p->n;j+=2) addbranch(b.branch,b.nb,i + p->loc[j+1].ival); break; } } if(leader == nextinst(c)) visit[leader]++; return b;}void EiC_peephole(code_t *C, int *visit){ int i, n,j; n = nextinst(C); for(i = 0; i < n; ++i) if(isgoto(C,i)) { j = i + ivalcode(C,i); if(j >= n) continue; if(opcode(C,j) == jmpu || opcode(C,i) == opcode(C,j)) { /*visit[i+ivalcode(C,i)]--;*/ ivalcode(C,i) += ivalcode(C,j); } }}int EiC_analyseCode(code_t *C){ /* returns the index to the last visited instruction */ block_t *block = NULL; int nb = 0; int i,j,rtn; int *visit; visit = calloc(sizeof(*visit),nextinst(C)+1); block = realloc(block,(nb+1)*sizeof(*block)); block[nb++] = initblock(C,0,visit); for(i=0;i<nb;++i) { for(j=0;j<block[i].nb;++j) { if(!visit[block[i].branch[j]]) { block = realloc(block,(nb+1)*sizeof(*block)); block[nb++] = initblock(C,block[i].branch[j],visit); } else visit[block[i].branch[j]]++; } } rtn = 0; for(i=0;i<=nextinst(C);) if(visit[i]) rtn = i++; else if(i < nextinst(C) && instline(C,i)) { EiC_warningerror("Unreachable code at line %d",instline(C,i)); for(;i<nextinst(C) && !visit[i];i++) ; } else i++; EiC_peephole(C,visit);/******* for(i=0;i<nextinst(C);++i) if(!visit[i]) setopcode(C,i,empty);*******/ freeblock(block,nb); free(visit); return rtn;}int EiC_checkPeepHole(token_t *e1,int op){ /* * A simple arithmetic optimizer: * do not add or subtract 0 * and do not multiply or divide by 1 */ int v = 0; if (isconst(e1->Type)) { if (op == '+' || op == '-') switch (EiC_gettype(e1->Type)) { CASE_INT: CASE_UINT:v = e1->Val.ival == 0; break; CASE_LONG: CASE_ULONG:v = e1->Val.lval == 0; break; CASE_FLOAT:v = e1->Val.dval == 0; break; } else if (op == '*') switch (EiC_gettype(e1->Type)) { CASE_INT: CASE_UINT:v = e1->Val.ival == 1; break; CASE_LONG: CASE_ULONG:v = e1->Val.lval == 1; break; CASE_FLOAT:v = e1->Val.dval == 1; break; } } return v;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -