From 343aacab2c691f5ba558d43ffdd43df954173604 Mon Sep 17 00:00:00 2001 From: clc5q <clc5q@git.zephyr-software.com> Date: Mon, 25 Feb 2008 23:56:54 +0000 Subject: [PATCH] Emit more dead EFLAGS annotations from functions with global EFLAGS uses. --- SMPBasicBlock.cpp | 36 +++++++++++++++++++++++++++++++++--- SMPBasicBlock.h | 7 +++++++ SMPInstr.cpp | 4 ++++ SMPInstr.h | 4 ++++ 4 files changed, 48 insertions(+), 3 deletions(-) diff --git a/SMPBasicBlock.cpp b/SMPBasicBlock.cpp index 9191aa31..11edc491 100644 --- a/SMPBasicBlock.cpp +++ b/SMPBasicBlock.cpp @@ -46,9 +46,17 @@ SMPBasicBlock::SMPBasicBlock(SMPFunction *Func, list<SMPInstr>::iterator First, this->BlockNum = SMP_BLOCKNUM_UNINIT; this->FirstAddr = First->GetAddr(); this->MyFunc = Func; + this->FirstFlagsDef = Last->GetAddr() + 1; + this->LastFlagsUse = First->GetAddr() - 1; + this->FlagsDeadAfterLastUse = false; + this->FlagsDeadBeforeFirstKill = false; list<SMPInstr>::iterator CurrInst = First; while (CurrInst != Last) { this->Instrs.push_back(CurrInst); + if (CurrInst->HasFlagsDef() && (CurrInst->GetAddr() < this->FirstFlagsDef)) + this->FirstFlagsDef = CurrInst->GetAddr(); + if (CurrInst->HasFlagsUse() && (CurrInst->GetAddr() > this->LastFlagsUse)) + this->LastFlagsUse = CurrInst->GetAddr(); ++CurrInst; } Last->SetTerminatesBlock(); @@ -568,6 +576,17 @@ bool SMPBasicBlock::IsRegDead(ea_t InstAddr, unsigned int RegIndex) const { return true; // no DEF-USE chains overlapped the instrumentation point } // end of SMPBasicBlock::IsRegDead() +// For functions in which the flags register is a global name, determine whether the flags +// are dead at the instruction located at addr. Do not call this function unless the +// FlagOp is a global name. +bool SMPBasicBlock::AreGlobalFlagsDead(ea_t addr, op_t FlagOp) { + if (this->FlagsDeadAfterLastUse && (addr > this->LastFlagsUse)) + return true; + if (this->FlagsDeadBeforeFirstKill && (addr <= this->FirstFlagsDef)) + return true; + return false; +} // end of SMPBasicBlock::AreGlobalFlagsDead() + // Mark the registers that are dead for each instruction in the block. void SMPBasicBlock::MarkDeadRegs(void) { // **!!** We will limit ourselves to local names for now. Most of the dead register @@ -579,6 +598,12 @@ void SMPBasicBlock::MarkDeadRegs(void) { FlagsOp.type = o_reg; FlagsOp.reg = X86_FLAGS_REG; char DeadString[MAXSTR]; + bool GlobalFlags = this->MyFunc->IsGlobalName(FlagsOp); + if (GlobalFlags) { + this->FlagsDeadAfterLastUse = (this->LiveOutSet.find(FlagsOp) == this->LiveOutSet.end()); + this->FlagsDeadBeforeFirstKill = ((this->UpExposedSet.find(FlagsOp) == this->UpExposedSet.end()) + && (this->KillSet.find(FlagsOp) != this->KillSet.end())); + } for (InstIter = this->Instrs.begin(); InstIter != this->Instrs.end(); ++InstIter) { DeadString[0] = '\0'; // First, put EFLAGS at beginning of string if it is dead. @@ -590,11 +615,16 @@ void SMPBasicBlock::MarkDeadRegs(void) { qstrncat(DeadString, " EFLAGS", sizeof(DeadString) - 1); } } - else if (this->MyFunc->IsGlobalName(FlagsOp)) { - ; + else if (GlobalFlags) { + if (this->AreGlobalFlagsDead((*InstIter)->GetAddr(), FlagsOp)) { + qstrncat(DeadString, " EFLAGS", sizeof(DeadString) - 1); + } + else { + ; #if SMP_DEBUG_OPTIMIZATIONS - msg("Global EFLAGS in %s\n", this->MyFunc->GetFuncName()); + msg("Global EFLAGS in %s\n", this->MyFunc->GetFuncName()); #endif + } } else { // EFLAGS are not locally used, but not global either; they are dead here qstrncat(DeadString, " EFLAGS", sizeof(DeadString) - 1); diff --git a/SMPBasicBlock.h b/SMPBasicBlock.h index e6ee3d01..2326643d 100644 --- a/SMPBasicBlock.h +++ b/SMPBasicBlock.h @@ -37,6 +37,8 @@ public: inline int GetNumber(void) const { return BlockNum; } inline list<list<SMPInstr>::iterator>::iterator GetFirstInstr(void) { return Instrs.begin(); }; inline list<list<SMPInstr>::iterator>::iterator GetLastInstr(void) { return Instrs.end(); }; + inline ea_t GetFirstFlagsDef(void) const { return FirstFlagsDef; }; + inline ea_t GetLastFlagsUse(void) const { return LastFlagsUse; }; inline list<list<SMPBasicBlock>::iterator>::iterator GetFirstPred(void) { return Predecessors.begin(); }; @@ -115,8 +117,13 @@ private: bool Returns; // contains a return instruction bool SharedTailChunk; // is part of a code chunk shared among functions bool IsLiveInStale; // Has LiveOutSet changed since LiveInSet was computed? + ea_t FirstFlagsDef; // addr of first instr that DEFs the flags + ea_t LastFlagsUse; // addr of last instr that USEs the flags + bool FlagsDeadAfterLastUse; // flags global, dead after last use in the block + bool FlagsDeadBeforeFirstKill; // flags global, dead before first DEF in block // Methods bool MDAlreadyKilled(op_t) const; // Was op_t killed by something already in KillSet? + bool AreGlobalFlagsDead(ea_t, op_t FlagOp); // Is the flags register FlagOp dead at ea_t? }; #endif diff --git a/SMPInstr.cpp b/SMPInstr.cpp index 0140d728..277280fa 100644 --- a/SMPInstr.cpp +++ b/SMPInstr.cpp @@ -54,6 +54,8 @@ SMPInstr::SMPInstr(ea_t addr) { this->JumpTarget = false; this->BlockTerm = false; this->DeadRegsString[0] = '\0'; + this->DefsFlags = false; + this->UsesFlags = false; return; } @@ -631,9 +633,11 @@ void SMPInstr::MDFixupDefUseLists(void) { } if (SMPDefsFlags[this->SMPcmd.itype]) { this->MDAddRegDef(X86_FLAGS_REG, false); + this->DefsFlags = true; } if (SMPUsesFlags[this->SMPcmd.itype]) { this->MDAddRegUse(X86_FLAGS_REG, false); + this->UsesFlags = true; } #if 1 diff --git a/SMPInstr.h b/SMPInstr.h index 952a4a7e..4a639dec 100644 --- a/SMPInstr.h +++ b/SMPInstr.h @@ -58,6 +58,8 @@ public: bool MDIsFrameAllocInstr(void) const; bool MDIsFrameDeallocInstr(bool UseFP, asize_t LocSize) const; bool MDUsesCalleeSavedReg(void) const; + inline bool HasFlagsDef(void) const { return DefsFlags; }; + inline bool HasFlagsUse(void) const { return UsesFlags; }; // Printing methods void PrintOperands(void) const; char *DestString(int OptType); @@ -81,6 +83,8 @@ private: bool JumpTarget; // Is Instr the target of any jumps or branches? bool BlockTerm; // This instruction terminates a basic block. char DeadRegsString[MAXSTR]; // Registers that are dead at this instruction + bool DefsFlags; // Instr DEFs the flags + bool UsesFlags; // Instr USEs the flags // Methods void BuildSMPDefUseLists(void); // Build DEF and USE lists for instruction void MDFixupDefUseLists(void); // Machine-dependent ad hoc fixes -- GitLab