?? 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 + -