📄 optim.c
字号:
insDst = GetNextChangedInstruction(i2,bb);
if (ediIsSaved == 0 || hasRegisterVariables) {
changedInstruction = GetNextChangedInstruction(insDst,bb);
insDst->Flags |= ADDED;
insDst->Flags &= ~ CHANGED;
strcpy(changedInstruction->Name,"\tpushl");
strcpy(changedInstruction->src,"\t%edi\n");
changedInstruction->dst[0] = 0;
}
if ((!strcmp(i2->src,"$0")) || (!strcmp(i2->src,"$0x0"))) {
strcpy(insDst->Name,"xor");
if (AvoidClobberingEax) {
strcpy(insDst->src,"%edi");
}
else {
strcpy(insDst->src,"%eax");
}
}
else if (i2->src[0] == '$') {
/*
Replicate in the eax register an 8 bit quantity
*/
int val = ReadValue(&i2->src[1]);
strcpy(insDst->Name,"movl");
sprintf(insDst->src,"$%d",(val << 24)|(val << 16)|(val << 8)|val);
}
else {
strcpy(insDst->Name,"movl");
strcpy(insDst->src,i2->src);
}
if (!AvoidClobberingEax) {
strcpy(insDst->dst,"%eax");
}
else {
strcpy(insDst->dst,"%edi");
}
State[EAX] = Nullst;
insDst = GetNextChangedInstruction(i1,bb);
if (strcmp(i1->src,"%edi")) {
if (!AvoidClobberingEax) {
strcpy(insDst->Name,"movl");
strcpy(insDst->src,i1->src);
strcpy(insDst->dst,"%edi");
}
else {
strcpy(insDst->Name,"xchg");
strcpy(insDst->src,"%eax");
strcpy(insDst->dst,"%edi");
}
}
else {
i1->Flags |= DELETED;
deleted++;
}
State[EDI] = Nullst;
insDst = GetNextChangedInstruction(ins,bb);
strcpy(insDst->Name,"rep");
FixCalls(ins,bb,idxInstruction);
insDst = GetNextChangedInstruction(in,bb);
if (isdword)
strcpy(insDst->Name,"stosl");
else if (isword)
strcpy(insDst->Name,"stosw");
else strcpy(insDst->Name,"stosb");
if (ediIsSaved == 0 || hasRegisterVariables) {
changedInstruction = GetNextChangedInstruction(insDst,bb);
insDst->Flags |= ADDED;
insDst->Flags &= ~ CHANGED;
strcpy(changedInstruction->Name,"\tpopl");
strcpy(changedInstruction->src,"\t%edi\n");
State[EDX] = Nullst;
}
Printf1("Optimization 22\n");
return(2);
}
}
skip1:
State[EAX] = State[ECX] = State[EDX] = Nullst;
Printf1("eax = ecx = edx = NULL\n");
if (State[ESI] && *State[ESI] == '_') State[ESI] = Nullst;
if (State[EDI] && *State[EDI] == '_') State[EDI] = Nullst;
if (State[EBX] && *State[EBX] == '_') State[EBX] = Nullst;
return 0;
}
static int FindStateChanges(void)
{
int result;
opcode = ins->Name;
savesrc = src = ins->src;
dst = ins->dst;
regdst = regsrc = isImmediate = aReg = 0;
result = 1;
assert((ins->Flags & TRUNCATED)==0);
if (ins->Flags & DELETED) return result;
if (ins->Flags & CHANGED) {
src = InstructionTable[ins->ChangedIdx].src;
dst = InstructionTable[ins->ChangedIdx].dst;
}
nextIns = &InstructionTable[idxInstruction+1];
lastIns = &InstructionTable[idxInstruction-1];
if (*dst == '%') {
dst++;
regdst = 1;
}
if (*src == '%') {
src++;
regsrc = 1;
}
else if (*src == '$')
isImmediate = 1;
isRedundant = 0;
isMovl = (ins->Flags & ISMOVL)?1:0;
if (dst[0] == '(') {
/*
replace
mov %esi (,%edi)
mov (,%edi) %esi
*/
if ( isMovl && nextIns->src[0] == '(' && !strcmp(src,nextIns->src)) {
if (!strcmp(ins->src,nextIns->dst)) {
nextIns->Flags |= DELETED;
Printf1("Optimization 37\n");
deleted++;
result++;
}
else if (regsrc) {
ChangeInstruction(nextIns,bb,nextIns->Name,ins->src,nextIns->dst);
}
}
return result;
}
/*
replace
mov %ecx;%esi
mov %esi,%ecx
*/
if (isMovl && regsrc && regdst &&
ins->SrcReg < EBP &&
(nextIns->Flags &(CHANGED|DELETED)) == 0) {
if ((nextIns->Flags & ISMOVL) &&
nextIns->src[0] == '%' && nextIns->dst[0] == '%') {
if (ins->DstReg == nextIns->SrcReg &&
ins->SrcReg == nextIns->DstReg) {
State[ins->DstReg] = Nullst;
nextIns->Flags |= DELETED;
deleted++;
return 2;
}
}
}
if (regdst && isMovl) {
if (ins->SrcReg == ins->DstReg) {
if (regsrc && !strcmp(src,dst)) {
ins->Flags |= DELETED;
deleted++;
return result;
}
}
/*
replace
movl %edx,%esi
movl (,%esi),%esi
with
movl (,%edx),%esi
*/
if (regsrc && nextIns->dst[0] == '%' &&
!strcmp(ins->dst,nextIns->dst) &&
*(unsigned long *)(nextIns->Name) == MOVL_CODE &&
(nextIns->Flags &(CHANGED|DELETED)) == 0 &&
ins->src[0] == '%' &&
nextIns->SrcReg == ins->DstReg ) {
doreplace(nextIns->src,ins->dst+1,ins->src+1,tbuf);
ChangeInstruction(nextIns,bb,nextIns->Name,tbuf,nextIns->dst);
ins->Flags |= DELETED;
deleted++;
State[ins->DstReg] = Nullst;
#if 0
printf("move optimization %s %s,%s -> %s %s,%s = %s %s,%s\n",
ins->Name,ins->src,ins->dst,
nextIns->Name,nextIns->src,nextIns->dst,
pins->Name,pins->src,pins->dst
);
#endif
return 2;
}
if (!regsrc && !isImmediate) {
if (State[EAX] && !strcmp(src,State[EAX])) {
Printf2("%s was in eax\n",State[EAX]);
if (ins->DstReg == EAX) {
ins->Flags |= DELETED;
deleted++;
}
else {
redundant++;
isRedundant = EAX;
}
}
if (State[EBX] && !strcmp(src,State[EBX])) {
Printf2("%s was in ebx\n",State[EBX]);
if (ins->DstReg == EBX) {
ins->Flags |= DELETED;
deleted++;
}
else {
redundant++;
isRedundant = EBX;
}
}
if (State[ECX] && !strcmp(src,State[ECX])) {
Printf2("%s was in ecx\n",State[ECX]);
if (ins->DstReg == ECX) {
ins->Flags |= DELETED;
deleted++;
}
else {
redundant++;
isRedundant = ECX;
}
}
if (State[EDX] && !strcmp(src,State[EDX])) {
Printf2("%s was in edx\n",State[EDX]);
if (ins->DstReg == EDX) {
ins->Flags |= DELETED;
deleted++;
}
else {
redundant++;
isRedundant = EDX;
}
}
if (State[ESI] && !strcmp(src,State[ESI])) {
Printf2("%s was in esi\n",State[ESI]);
if (ins->DstReg == ESI) {
ins->Flags |= DELETED;
deleted++;
}
else {
redundant++;
isRedundant = ESI;
}
}
if (State[EDI] && !strcmp(src,State[EDI])) {
Printf2("%s was in edi\n",State[EDI]);
if (ins->DstReg == EDI) {
ins->Flags |= DELETED;
deleted++;
}
else {
redundant++;
isRedundant = EDI;
}
}
if (isRedundant &&
src[0] != '$' && (ins->Flags & (CHANGED|DELETED)) == 0) {
ChangeRedundantLoad(ins,isRedundant,bb,idxInstruction);
}
}
if (ins->Flags & DELETED)
return(result);
if (isRedundant == 0 &&
regsrc == 0 &&
(ins->Flags & SRCDEREFERENCE) == 0 &&
((ins->Flags & SRCOFFSET) == 0 || ins->SrcReg == EBP)) {
State[ins->DstReg] == src;
}
}
if (ins->DstReg > ESP) {
if (ins->DstReg < SP+1) State[ins->DstReg-ESP] = Nullst;
else if ((ins->Flags & ISGENERICMOVE) == 0) {
int r;
r = ins->DstReg & 0xFF;
if (r < ESP) {
State[r] = Nullst;
Printf2("%s = NULL\n",RegisterNames[r]);
}
r = (ins->DstReg >> 8) & 0xFF;
if (r < ESP) {
State[r] = Nullst;
Printf2("%s = NULL\n",RegisterNames[r]);
}
}
}
if (isMovl &&
regsrc &&
regdst &&
isImmediate == 0 &&
(ins->Flags&CHANGED) == 0 &&
ins->SrcReg < EBP &&
ins->DstReg < EBP) {
int i = RegToRegCopy();
if (i) return i;
}
/*
This should have taken into account the fact that after an
orl %eax,%eax
jne _$label
%eax is zero. Then any 'xor %eax,%eax' after this can be deleted
The results are disappointing. 210 bytes gained from 543188...
*/
if (isMovl == 0 && regsrc && regdst
&& ins->SrcReg == ins->DstReg
&& opcode[0] == 'o' && opcode[1] == 'r'
&& (opcode[2] == 0 || opcode[2] == 'l')
&& ins->SrcReg < EBP) {
if ((nextIns->Flags & (CHANGED|DELETED)) == 0
&& !strcmp(nextIns->Name,"jne")) {
Instruction *tmpins = nextIns;
nextIns++;
if ((nextIns->Flags & (CHANGED|DELETED)) == 0) {
if (nextIns->SrcReg == ins->SrcReg &&
nextIns->DstReg == ins->SrcReg &&
nextIns->src[0] == '%' &&
nextIns->dst[0] == '%' &&
!strcmp(nextIns->Name,"xor")) {
nextIns++;
if (strcmp(nextIns->Name,"jmp")) {
nextIns--;
nextIns->Flags |= DELETED;
deleted++;
Printf1("Optimization 47\n");
}
else {
// This is ridiculous. Changed from
// 542968 to 542924: 44 bytes saved only!
// should be faster though, since a jump is saved
if (!strncmp(nextIns->End,tmpins->src,strlen(tmpins->src))
&& ins->SrcReg == EAX) {
int lab = atoi(nextIns->src+2);
if (lab == lastLabel) {
ChangeInstruction(tmpins,bb,"je",nextIns->src,"");
nextIns--;
nextIns->Flags |= DELETED;
deleted++;
nextIns++;
nextIns->Flags |= DELETED;
deleted++;
return(4);
}
}
}
}
else if (nextIns->src[0] == '$' &&
nextIns->src[1] == '0' &&
nextIns->src[2] == 0 &&
(!strcmp(nextIns->Name,"movl") || (nextIns->Flags & ISCOMPARE))) {
ChangeInstruction(nextIns,bb,nextIns->Name,ins->src,nextIns->dst);
Printf1("Optimization 47\n");
return(3);
}
}
}
return(result);
}
if (isMovl == 0){
int r;
if (ins->Flags & ISCOMPARE)
return compare();
else if (ins->Name[0] == 'c' && ins->Name[1] == 'm' &&
ins->Name[2] == 'p') {
r = ImproveSetEqual(0);
if (r) return r;
}
}
if ((ins->Flags & ISGENERICMOVE) == 0) {
/* delete additions and substractions of zero */
if ((ins->Flags & (CHANGED|DELETED))==0 &&
(opcode[0] == 'a' && opcode[1] == 'd' && opcode[2] == 'd') ||
(opcode[0] == 's' && opcode[1] == 'u' && opcode[2] == 'b')) {
int reg;
if (isImmediate && src[1] == '0') {
if (src[2] == 0 || (src[2] == 'x' && src[3] == '0' && src[4] == 0)) {
ins->Flags |= DELETED;
return result;
}
}
#if 1
if (!isImmediate && !regsrc) {
reg = CheckValueAlreadyLoaded(ins->src);
if (reg) {
sprintf(tbuf,"%%%s",RegisterNames[reg]);
ChangeInstruction(ins,bb,ins->Name,tbuf,ins->dst);
}
}
#endif
lastIns = GetLastInstruction(idxInstruction);
/*
Replace
addl $-1,reg
by
inc reg
*/
if (((ins->Flags & CHANGED) == 0) && isImmediate && src[1] == '-'
&& src[2] == '1' && src[3] == 0) {
unsigned char *op;
if (regdst) {
tbuf[0] = '%';
strcpy(tbuf+1,dst);
}
else strcpy(tbuf,dst);
if (*opcode == 'a')
op = "decl";
else
op = "incl";
if (*dst != '%') doclobber(dst,10000);
ChangeInstruction(ins,bb,op,tbuf,"");
Printf1("addl/subl->inc/dec\n");
}
else
/*
Replace postincrement from
mov mem,reg1 load value
mov reg1,reg2 save old value in reg2
inc reg1 add offset
mov reg1,mem store updated value
to
mov mem,reg1 load value
inc reg1 add offset
xchg reg1,mem store new value AND reload old
*/
if ((ins->Flags & CHANGED) == 0 && recursion == 0 &&
(ins->Flags & ISREGDST) &&
isImmediate && idxInstruction >1) {
if ((lastIns->Flags & ISREGSRC) && (lastIns->Flags & ISREGDST)
&& (lastIns->Flags & ISMOVL) &&
lastIns->DstReg == ins->DstReg &&
!IsAliveValue(bb,idxInstruction+2,ins->DstReg)) {
Instruction *tmp;
tmp = lastIns - 1;
if (((tmp->Flags & CHANGED)==0) &&
(tmp->Flags & ISMOVL) &&
(tmp->Flags & ISREGSRC) == 0 &&
tmp->DstReg == lastIns->SrcReg) {
if ((nextIns->Flags & ISREGSRC) && !strcmp(tmp->src,nextIns->dst)) {
unsigned char *srcC;
if (lastIns->Flags & CHANGED) {
srcC = InstructionTable[lastIns->ChangedIdx].src;
}
else
srcC = lastIns->src;
lastIns->Flags |= DELETED;
deleted++;
tmp->Flags &= ~DELETED;
if (opcode[0] == 's') {
sprintf(tbuf,"$-%s",src+1);
}
else strcpy(tbuf,src);
ChangeInstruction(tmp,bb,"movl",nextIns->dst,srcC);
insDst = ChangeInstruction(ins,bb,"add",tbuf,nextIns->dst);
nextIns->Flags |= DELETED;
deleted++;
doclobber(insDst->src,10000);
if (lastIns->SrcReg < ESP)
State[lastIns->SrcReg] = Nullst;
Printf3("%s = %s = NULL\n",RegisterNames[lastIns->SrcReg],
RegisterNames[lastIns->DstReg]);
Printf1("Optimization 13 (postincrement)\n");
return(result+1);
}
}
else if ((lastIns->Flags & CHANGED) == 0 &&
!hasRegisterVariables) {
unsigned char *minus;
if (opcode[0] == 's') minus = "-";
else minus = "";
sprintf(tbuf,"%s%s(%s)",minus,ins->src+1,lastIns->src);
ChangeInstruction(ins,bb,"leal",tbuf,ins->dst);
lastIns->Flags |= DELETED;
delete
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -