📄 cfuncoptim.cpp
字号:
// Copyright(C) 1999-2005 LiuTaoTao,bookaa@rorsoft.com
#include "stdafx.h"
#include "CISC.H"
#include "cexe2c.h"
#include "CStrategy.h"
//#define VarName Q->VarName
#define m_instr_list Q->m_instr_list
#define m_exprs Q->m_exprs
#define m_head_off Q->m_head_off
#define m_funcname Q->m_funcname
bool CFuncOptim::Simplify_Instr()
//看看简单指令能不能变成i_Assign
{
INSTR_LIST* list = this->m_instr_list;
POSITION pos = list->GetHeadPosition();
while (pos)
{
PINSTR p = list->GetNext(pos);
if (p->type == i_GetAddr)
{
p->type = i_Assign;
st_InstrAddOn* pnew = new st_InstrAddOn;
pnew->type = IA_GetAddress;
pnew->pChild = p->va_r1.pao;
p->va_r1.pao = pnew;
return true;
}
if (p->type == i_Add && p->var_r2.type == v_Immed)
{
p->type = i_Assign;
st_InstrAddOn* pnew = new st_InstrAddOn;
pnew->type = IA_AddImmed;
pnew->addimmed.iAddon = p->var_r2.d;
pnew->pChild = p->va_r1.pao;
p->va_r1.pao = pnew;
p->var_r2.type = v_Invalid;
return true;
}
if (p->type == i_Imul && p->var_r2.type == v_Immed)
{
p->type = i_Assign;
st_InstrAddOn* pnew = new st_InstrAddOn;
pnew->type = IA_MulImmed;
pnew->addimmed.iAddon = p->var_r2.d;
pnew->pChild = p->va_r1.pao;
p->va_r1.pao = pnew;
p->var_r2.type = v_Invalid;
return true;
}
}
return false;
}
bool CFuncOptim::Address_to_Add()
//看看i_Address能不能变成i_Add
{
INSTR_LIST* list = this->m_instr_list;
POSITION pos = list->GetHeadPosition();
while (pos)
{
PINSTR p = list->GetNext(pos);
if (p->type == i_Address)
{
if (p->var_r2.type == v_Invalid)
{
p->i1 = 0;
if (p->i2 == 0)
{
p->type = i_Assign;
return true;
}
//现在i2不为零,要变为add
p->var_r2.type = v_Immed;
p->var_r2.d = p->i2;
p->var_r2.thevar = NULL;
p->i2 = 0;
p->type = i_Add;
return true;
}
if (p->i2 == 0
&& VAR::IsSame(&p->var_r1, &p->var_r2)
&& st_InstrAddOn::IsSame(p->va_r1.pao, p->va_r2.pao))
{
p->var_r2.type = v_Invalid;
p->va_r2.pao = NULL;
p->var_r2.type = v_Immed;
p->var_r2.d = p->i1 + 1;
p->var_r2.thevar = NULL;
p->type = i_Imul;
p->i1 = 0;
return true;
}
if (p->i1 > 1 && p->var_r2.type != v_Invalid)
{
st_InstrAddOn* pnew = new st_InstrAddOn;
pnew->type = IA_MulImmed;
pnew->addimmed.iAddon = p->i1;
pnew->pChild = p->va_r2.pao;
p->va_r2.pao = pnew;
p->i1 = 1;
return true;
}
if (p->i1 == 1 && p->i2 == 0)
{//这是个Add
p->type = i_Add;
return true;
}
}
}
return false;
}
bool CFuncOptim::pcode_1()
{ // 如果cmp和jxx紧靠,把cmp和jxx合并
INSTR_LIST* list = this->m_instr_list;
POSITION pos = list->GetHeadPosition();
while (pos)
{
POSITION savpos = pos;
PINSTR pcmp = list->GetNext(pos);
if (pcmp->type == i_Cmp)
{
PINSTR pjxx = list->GetAt(pos);
if (pjxx->type == i_Jump && pjxx->jmp.jmp_type != JMP_jmp)
{
pjxx->var_r1 = pcmp->var_r1;
pjxx->va_r1.pao = pcmp->va_r1.pao;
pjxx->var_r2 = pcmp->var_r2;
pjxx->va_r2.pao = pcmp->va_r2.pao;
list->RemoveAt(savpos);
return true;
} // 删除的是i_Cmp,留的是jxx,这样不用动label
else
{//孤怜怜的cmp,删掉算了
list->RemoveAt(savpos);
return true;
}
}
}
return false;
}
bool CFuncOptim::ana_Flow()
{ // 流程分析
INSTR_LIST *list = this->m_instr_list;
PINSTR first = list->GetHead();
// 对这个i_Begin到i_End之间的进行分析,标出所有的i_Begin和i_End
CInstrList the(list);
return the.Flow_a(first);
}
bool CFuncOptim::expr_never_use_after_this(VAR* pvar, PINSTR p0, INSTR_LIST* oldroad)
{ // 我必须知道,必须知道!
INSTR_LIST* list = this->m_instr_list;
POSITION pos = list->Find(p0);
while (pos)
{
PINSTR p = list->GetNext(pos);
if (p->type == i_Label)
{ // 根本不用考虑
oldroad->AddHead(p);
continue;
}
if (VAR::IsSame(pvar, &p->var_w))
return true;
if (VAR::IsSame(pvar, &p->var_r1))
return false;
if (VAR::IsSame(pvar, &p->var_r2))
return false;
// 因为 i_Jump 也可以带参数,所以要先检查
if (p->type == i_Jump)
{ // 要防止死结
if (! oldroad->Find(p->jmp.the_label))
{
oldroad->AddHead(p->jmp.the_label);
if (! expr_never_use_after_this(pvar,p->jmp.the_label,oldroad))
return false;
}
if (p->jmp.jmp_type == JMP_jmp)
return true;
continue;
}
}
return true;
}
bool CFuncOptim::MakeSure_NotRef_in_Range(VAR* pvar, PINSTR p1, PINSTR p2)
{ // 确认从p1到p2没人用过pvar
// 不包括p1在内,也不包括p2
INSTR_LIST* list = this->m_instr_list;
POSITION pos = list->Find(p1);
list->GetNext(pos); // skip p1
while (pos)
{
PINSTR p = list->GetNext(pos);
if (p == p2)
return true;
if (VAR::IsSame(pvar, &p->var_w))
return false;
if (VAR::IsSame(pvar, &p->var_r1))
return false;
if (VAR::IsSame(pvar, &p->var_r2))
return false;
}
error("why here 8u3");
return false;
}
bool CFuncOptim::ClassSubFuncProcess()
{//return false 继续下一步的分析
CFuncType* pfctype = this->Q->m_functype;
if (pfctype == NULL || pfctype->m_class == NULL)
return false;
VarTypeID id = g_VarTypeManage->Class2VarID(pfctype->m_class);
id = g_VarTypeManage->GetAddressOfID(id);
this->Q->Fill_this_ECX(id);
return false;
}
bool CFuncOptim::Var_Split()
{
POSITION pos = this->m_exprs->vList->GetHeadPosition();
while (pos)
{
M_t* pvar = this->m_exprs->vList->GetNext(pos);
if (pvar->type == MTT_reg)
{
VAROPTM_LIST used_list;
//分析过的instr
Get_Var_Use_Flow(used_list, pvar);
if (TryDistinguishVar(used_list, pvar))
{
prt_var_uselist(used_list);
return true;
}
}
}
return false;
}
bool CFuncOptim::DataType_Flow()
{//数据类型流分析
POSITION pos = m_instr_list->GetHeadPosition();
while (pos)
{
PINSTR p = m_instr_list->GetNext(pos);
if (p->type == i_GetAddr
&& p->var_w.thevar != NULL
&& g_VarTypeManage->GetPointTo(p->var_w.thevar->m_DataTypeID) != 0
&& p->var_r1.thevar != NULL
&& g_VarTypeManage->is_simple(p->var_r1.thevar->m_DataTypeID)
&& GG_VarType_ID2Size(g_VarTypeManage->GetPointTo(p->var_w.thevar->m_DataTypeID))
>= GG_VarType_ID2Size(p->var_r1.thevar->m_DataTypeID))
{
p->var_r1.thevar->m_DataTypeID = g_VarTypeManage->GetPointTo(p->var_w.thevar->m_DataTypeID);
//仅仅改一下是不够的
p->var_r1.opsize = GG_VarType_ID2Size(p->var_r1.thevar->m_DataTypeID);
p->var_r1.thevar->size = GG_VarType_ID2Size(p->var_r1.thevar->m_DataTypeID);
this->m_exprs->Enlarge_Var(p->var_r1.thevar, this->m_instr_list);
return true;
}
}
return false;
}
//--------------------------------------------------
bool CFuncOptim::optim_once_new()
{//注意,这时cmp与jxx还没有合并
POSITION pos = this->m_exprs->vList->GetHeadPosition();
while (pos)
{
M_t* p = this->m_exprs->vList->GetNext(pos);
//if (p->type == MTT_reg)
if (p->type != MTT_var)
{
if (Optim_var_NT(p))
return true;
}
}
#if 0
INSTR_LIST* list = this->m_instr_list;
POSITION pos = list->GetHeadPosition();
while (pos)
{
PINSTR p = list->GetNext(pos);
if (p->var_w.type && p->var_w.thevar)
{
if (Optim_var_NT(p->var_w.thevar))
return true;
}
if (p->var_r1.type && p->var_r1.thevar)
{
if (Optim_var_NT(p->var_r1.thevar))
return true;
}
if (p->var_r2.type && p->var_r2.thevar)
{
if (Optim_var_NT(p->var_r2.thevar))
return true;
}
}
#endif
return false;
}
static st_VarOptm* used_list_Find(PINSTR pinstr, VAROPTM_LIST& used_list)
{
POSITION pos = used_list.GetHeadPosition();
while (pos)
{
st_VarOptm* p = used_list.GetNext(pos);
if (p->pinstr == pinstr)
return p;
}
return NULL;
}
BYTE GetVarFinger_INSTR(M_t* pvar, PINSTR p)
//00: nothing with
//01: read
//02: write
//03: read and write
{
BYTE r = 0;
if (pvar == p->var_w.thevar)
{
r |= 2;
if (p->var_w.part_flag != 0)
r|=4;
}
if (pvar == p->var_r1.thevar)
{
r |= 1;
if (p->var_r1.part_flag != 0)
r|=4;
}
if (pvar == p->var_r2.thevar)
{
r |= 1;
if (p->var_r2.part_flag != 0)
r|=4;
}
return r;
}
void CFuncOptim::prt_var_uselist(VAROPTM_LIST& used_list)
{
log_prtl("%s","===========");
INSTR_LIST *list = this->m_instr_list;
POSITION pos = used_list.GetHeadPosition();
while (pos)
{
st_VarOptm* the = used_list.GetNext(pos);
PINSTR p = the->pinstr;
if (p->type == i_Jump)
{
if (p->jmp.jmp_type == JMP_jmp)
{
log_prtl(" jmp %x", p->jmp.jmpto_off);
}
else
{
log_prtl(" jxx %x", p->jmp.jmpto_off);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -