📄 cfuncoptim.cpp
字号:
}
if (n >= 2)
{
const char* pb = tbl_c + n - 2;
PINSTR* pi = tbl_pinstr + n - 2;
if (strcmp(pb, "2E") == 0 || strcmp(pb, "3E") == 0 || strcmp(pb, "6E") == 0
|| strcmp(pb, "7E") == 0)
{
g_CStrategy.AddOne_CanDelete(pvar, pi[0], "write and end, delete it");
return true;
}
if (strcmp(pb, "63") == 0)
{
g_CStrategy.AddOne_CanEliminate_63(pvar, pi[0], pi[1], "63");
return true;
}
if (strcmp(pb, "22") == 0 || strcmp(pb, "26") == 0
|| strcmp(pb, "32") == 0 || strcmp(pb, "36") == 0
|| strcmp(pb, "62") == 0 || strcmp(pb, "66") == 0)
{
g_CStrategy.AddOne_CanDelete(pvar, pi[0], "Write and Write, delete first");
return true;
}
if (strcmp(pb, "23") == 0)
{
if (pvar->type != MTT_tem)
{
g_CStrategy.AddOne_CanEliminate_21E(pvar,pi[0],pi[1],"23");
return true;
}
}
}
if (n >= 3)
{
const char* pb = tbl_c + n - 3;
char fpt[4]; //finger point
strcpy(fpt,pb);
assert(strlen(fpt) == 3);
if (fpt[2] == '6' || fpt[2] == '2')
fpt[2] = 'E';
PINSTR* pi = tbl_pinstr + n - 3;
if (strcmp(fpt, "25E") == 0 && pi[1]->va_r1.pao == NULL)
{
g_CStrategy.AddOne_CanEliminate_25E(pvar,pi[0],pi[1],"25E");
return true;
}
if (strcmp(fpt, "61E") == 0)
{
g_CStrategy.AddOne_CanEliminate_63(pvar, pi[0], pi[1], "61E");
return true;
}
if (strcmp(fpt, "65E") == 0)
{
if (pi[1]->va_r1.pao == NULL || pi[1]->va_r1.pao->type != IA_GetAddress)
{
//如果 A=3, B=&A显然不能变成 A=&3
g_CStrategy.AddOne_CanEliminate_63(pvar,pi[0],pi[1],"65E");
return true;
}
}
if (strcmp(fpt, "31E") == 0)
{
if (pi[0]->type == i_Sub || pi[0]->type == i_Add)
if (pi[0]->var_w.thevar == pi[0]->var_r1.thevar)
if (pi[1]->type == i_Cmp && pi[0]->var_w.thevar == pi[0]->var_r1.thevar)
{
//log_prtl("31E find");
g_CStrategy.AddOne_CanEliminate_31E(pvar,pi[0],pi[1],"31E");
return true;
}
}
if (strcmp(fpt, "21E") == 0)
{
if (pvar->type != MTT_tem)
{
g_CStrategy.AddOne_CanEliminate_21E(pvar,pi[0],pi[1],"21E");
return true;
}
}
}
if (n >= 4)
{
const char* pb = tbl_c + n - 4;
PINSTR* pi = tbl_pinstr + n - 4;
char fpt[5]; //finger point
strcpy(fpt,pb);
assert(strlen(fpt) == 4);
if (fpt[3] == '6' || fpt[3] == '2')
fpt[3] = 'E';
if (strcmp(fpt, "311E") == 0)
{
if (pi[0]->type == i_Sub || pi[0]->type == i_Add)
if (pi[0]->var_w.thevar == pi[0]->var_r1.thevar)
if (pi[1]->type == i_Cmp && pi[0]->var_w.thevar == pi[1]->var_r1.thevar)
if (pi[2]->type == i_Cmp && pi[0]->var_w.thevar == pi[2]->var_r1.thevar)
{
log_prtl("311E find");
signed int d = pi[0]->var_r2.d;
if (pi[0]->type == i_Add)
d = -d;
pi[1]->var_r2.d += d;
pi[2]->var_r2.d += d;
m_instr_list->RemoveAt(m_instr_list->Find(pi[0]));
return true;
}
}
}
}
return false;
}
bool CFuncOptim::Optim_var_NT(M_t* pvar)
//SuperC_func: 只在<CFuncOptim::optim_once_new>中使用
//试图对这个var优化
{
if (pvar == NULL)
return false;
VAROPTM_LIST used_list;
//分析过的instr
Get_Var_Use_Flow(used_list, pvar);
//先得到变量使用图
//先优化,再分
if (Optim_var_flow_NT(used_list, pvar))
{
prt_var_uselist(used_list);
return true;
}
return false;
}
static int static_n = 0;
static int static_tbl[80];
void CFuncOptim::TryDistinguishVar_1(VAROPTM_LIST& volist, M_t* pvar, POSITION pos,
int* pglobalstep)
//这个函数要递归的
{
int step = *pglobalstep;
//之所以要有一个pglobalstep,是为了得到下一个step
while (pos)
{
st_VarOptm* the = volist.GetNext(pos);
if (the->bJxx)
{
st_VarOptm* plabel = used_list_Find(the->pinstr->jmp.the_label, volist);
assert(plabel != 0);
TryDistinguishVar_1(volist, pvar, volist.Find(plabel), pglobalstep);
if (the->pinstr->jmp.jmp_type == JMP_jmp)
{
step = *pglobalstep;
*pglobalstep = step+1;
}
continue;
}
if (the->pinstr->type == i_Label)
{
continue; //不需要做什么事情
}
if (the->pinstr->type == i_Return)
{
step = *pglobalstep;
*pglobalstep = step+1;
continue;
}
//
assert(the->rw != 0);
if (the->rw & 1) //read
{
if (the->varstep_r == step)
return;
if (the->varstep_r != 0 && the->varstep_r != step)
{//撞车了,怎么办?
int i1 = min(the->varstep_r, step);
int i2 = max(the->varstep_r, step);
assert(static_n < 80);
static_tbl[static_n++] = i1;
static_tbl[static_n++] = i2;
return;
}
the->varstep_r = step;
}
if (the->rw & 2) //write
{
if (the->varstep_w != 0)
return; //有人做过了,不必再做
step = *pglobalstep;
step++;
*pglobalstep = step;
the->varstep_w = step;
}
}
}
bool CFuncOptim::IfAnyThisStep(int i, VAROPTM_LIST& volist)
{
POSITION pos = volist.GetHeadPosition();
while (pos)
{
st_VarOptm* the = volist.GetNext(pos);
if (the->varstep_r == i)
return true;
if (the->varstep_w == i)
return true;
}
return false;
}
bool Get_pair(int& out_i1, int& out_i2)
{
//找i2最大的那个
int savi;
int max_i2 = 0;
for (int i=0; i<static_n; i+= 2)
{
int i1 = static_tbl[i];
int i2 = static_tbl[i+1];
if (i2 > max_i2)
{
max_i2 = i2;
out_i2 = i2;
out_i1 = i1;
savi = i;
}
}
if (max_i2 == 0)
return false;
static_tbl[savi] = 0; //清掉,以免重复使用
static_tbl[savi+1] = 0;
return true;
}
void Replace_i2_with_i1(VAROPTM_LIST& volist, int i1, int i2)
{
POSITION pos = volist.GetHeadPosition();
while (pos)
{
st_VarOptm* the = volist.GetNext(pos);
if (the->varstep_r == i2)
the->varstep_r = i1;
if (the->varstep_w == i2)
the->varstep_w = i1;
}
}
void CFuncOptim::Replace_Var_vo(VAROPTM_LIST& volist, int step, M_t* pvar, M_t* pnew)
{
POSITION pos = volist.GetHeadPosition();
while (pos)
{
st_VarOptm* p = volist.GetNext(pos);
if (p->varstep_r == step)
{
if (p->pinstr->var_r1.thevar == pvar)
p->pinstr->var_r1.thevar = pnew;
if (p->pinstr->var_r2.thevar == pvar)
p->pinstr->var_r2.thevar = pnew;
}
if (p->varstep_w == step)
{
if (p->pinstr->var_w.thevar == pvar)
p->pinstr->var_w.thevar = pnew;
}
}
}
PCSTR my_itoa(int i);
bool CFuncOptim::TryDistinguishVar(VAROPTM_LIST& volist, M_t* pvar)
//看看能不能把一个var从逻辑上分为两个
//开始写写varstep_r和varstep_w
{
if (pvar->type != MTT_reg)
return false; //先只处理reg类型
if (strcmp("ESI",pvar->GetName()) == 0)
pvar->GetName();
static_n = 0;
int step = 1;
TryDistinguishVar_1(volist, pvar,
volist.GetHeadPosition(),
&step);
for (;;)
{
int i1, i2;
if (!Get_pair(i1, i2))
break;
Replace_i2_with_i1(volist, i1, i2);
}
int n = 0;
int tblstep[120];
for (int i=1; i<step+1; i++)
{
if (IfAnyThisStep(i, volist))
{
tblstep[n++] = i;
}
}
if (n > 1)
{
log_prtl("find var distinguish");
for (int i=0; i<n; i++)
{
if (i == 0)
continue; //保留第一个
M_t* pnew = new M_t;
*pnew = *pvar;
strcat(pnew->namestr, "_");
strcat(pnew->namestr, my_itoa(i));
this->m_exprs->vList->AddTail(pnew);
Replace_Var_vo(volist, tblstep[i], pvar, pnew);
}
return true;
}
return false;
}
void CFuncOptim::Get_Var_Use_Flow(VAROPTM_LIST& used_list, M_t* pvar)
//只写used_list.pinstr 的 used_list.rw,不写varstep_r和varstep_w
{
PINSTR tbl_label[728];
int num = 0;
INSTR_LIST *list = this->m_instr_list;
POSITION pos = list->GetHeadPosition();
while (pos)
{
POSITION savpos = pos;
PINSTR p = list->GetNext(pos);
BYTE c = GetVarFinger_INSTR(pvar, p);
if (c != 0 || p->type == i_Label || p->type == i_Return)
{//只有这些才是我关心的
st_VarOptm* the = new st_VarOptm;
the->pinstr = p;
the->rw = c;
used_list.AddTail(the);
}
if (p->type == i_Jump)
{
tbl_label[num++] = p->jmp.the_label;
st_VarOptm* the = new st_VarOptm;
the->pinstr = p;
the->rw = c;
the->bJxx = true;
used_list.AddTail(the);
//这样,一条jump可能会加两次,前一次是它用到了本变量cmp(v,?)
//后一条是它jxx了
}
}
//----------------------------------
//要优化这个序列,把没用的jmp和label去掉
while (Optim_Var_Flow(used_list))
{
}
}
void CFuncOptim::Prt_Var_Flow(PCSTR varname)
{
M_t* pvar = this->m_exprs->GetVarByName(varname);
if (pvar == NULL)
{
log_prtl("not find var: %s", varname);
return;
}
log_prtl("find var: %s", varname);
VAROPTM_LIST used_list; //分析过的instr
Get_Var_Use_Flow(used_list, pvar);
prt_var_uselist(used_list);
CString s = Get_var_finger_NT(used_list, pvar);
log_prtl("%s", (PCSTR)s);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -