//----------------------------------------------------------------------------- bool AsmOptimization::Optimize(AsmCode& code) { bool res = false; for (int i = 0; i < code.Size(); ++i) { res = Optimize(code, i) || res; } return res; }
bool PopToUpPushToDown::Action(AsmCode& code, AsmCmd1* cmd, int i, int inc) { int j = i; while (0 < j && j + 1 < code.Size() && !UsesStack(code[j + inc]) && !IsArgument(cmd->GetArgument(), code[j + inc])) { j += inc; } code.Move(i, j); return j != i; }
//----------------------------------------------------------------------------- bool AddSubZero::Optimize(AsmCode& code, int index) { if (index == code.Size()) { return false; } AsmCmd2* cmd = dynamic_cast<AsmCmd2*>(code[index]); if (cmd && (*cmd == cmdSUB || *cmd == cmdADD) && *cmd->GetSecond() == "0") { code.Delete(index); return true; } return false; }
bool PopToUpPushToDown::Optimize(AsmCode& code) { bool res = false; for (int i = 0; i < code.Size(); ++i) { AsmCmd1* cmd = dynamic_cast<AsmCmd1*>(code[i]); if (cmd && *cmd == cmdPUSH) { res = Action(code, cmd, i, 1) || res; } else if (cmd && *cmd == cmdPOP) { res = Action(code, cmd, i, -1) || res; } } return res; }
bool PushPopOptimization::Optimize(AsmCode& code, int index) { if (index + 1 == code.Size()) { return false; } AsmCmd1* cmd1 = dynamic_cast<AsmCmd1*>(code[index]); AsmCmd1* cmd2 = dynamic_cast<AsmCmd1*>(code[index + 1]); if (cmd1 && cmd2 && *cmd1 == cmdPUSH && *cmd2 == cmdPOP) { if (*cmd1->GetArgument() == cmd2->GetArgument()) { code.Delete(index, index + 1); return true; } } return false; }
bool PushPopToMovOptimization::Optimize(AsmCode& code, int index) { if (index + 1 == code.Size()) { return false; } AsmCmd1* cmd1 = dynamic_cast<AsmCmd1*>(code[index]); AsmCmd1* cmd2 = dynamic_cast<AsmCmd1*>(code[index + 1]); if (cmd1 && cmd2 && *cmd1 == cmdPUSH && *cmd2 == cmdPOP && *cmd1->GetArgument() != cmd2->GetArgument() && !IsMemory(cmd1->GetArgument()) && !IsMemory(cmd2->GetArgument())) { AsmCmd2* optCmd = new AsmCmd2(cmdMOV, cmd2->GetArgument(), cmd1->GetArgument()); code.Delete(index, index + 1); code.Insert(optCmd, index); return true; } return false; }
bool MovChainOptimization::Optimize(AsmCode& code, int index) { if (index + 1 == code.Size()) { return false; } AsmCmd2* cmd1 = dynamic_cast<AsmCmd2*>(code[index]); AsmCmd2* cmd2 = dynamic_cast<AsmCmd2*>(code[index + 1]); if (cmd1 && cmd2 && *cmd1 == cmdMOV && *cmd2 == cmdMOV && *cmd1->GetFirst() != EBP && *cmd1->GetSecond() != ESP && *cmd2->GetSecond() == cmd1->GetFirst() && !IsMemory(cmd1->GetSecond()) && !IsMemory(cmd2->GetFirst())) { AsmCmd2* optCmd = new AsmCmd2(cmdMOV, cmd2->GetFirst(), cmd1->GetSecond()); code.Delete(index, index + 1); code.Insert(optCmd, index); return true; } return false; }