diff --git a/include/base/SMPFunction.h b/include/base/SMPFunction.h index 2e06a7fe9714b664d5cc87125823fbd54231703e..ee169e6075ed685c3e462602f02f68fa47dccd71 100644 --- a/include/base/SMPFunction.h +++ b/include/base/SMPFunction.h @@ -339,6 +339,7 @@ public: } inline bool IsJumpFollowBlock(STARS_ea_t InstAddr) const { return (JumpFollowNodesSet.find(InstAddr) != JumpFollowNodesSet.end()); } bool IsInStackPtrCopySet(const STARSOpndTypePtr &CurrOp); + bool IsDefnInStackPtrCopySet(const STARSOpndTypePtr &CurrOp, const STARS_ea_t &DefAddr) const; inline bool DoesStackFrameExtendPastStackTop(void) const { return StackFrameExtendsPastStackTop; }; inline bool IsRegPreserved(std::size_t RegNum) const { return (PreservedRegsBitmap[RegNum] != 0); }; diff --git a/src/base/SMPBasicBlock.cpp b/src/base/SMPBasicBlock.cpp index d774b5d2a3a5613a3d45182a065bf80871135727..9e4c5a0d45b546eff37af40839db228eb1c970b2 100644 --- a/src/base/SMPBasicBlock.cpp +++ b/src/base/SMPBasicBlock.cpp @@ -1144,28 +1144,36 @@ bool SMPBasicBlock::ComputeReachesOutSet(void) { // Add DefOp, remove previous defs of DefOp that now do not reach the end of the block. void SMPBasicBlock::UpdateDownExposedDefs(STARSOpndTypePtr DefOp, STARS_ea_t InstAddr) { -#if 1 - // Only purpose of the DownExposedDefnSet is to track stack pointer copies, so save time. - if (!this->GetFunc()->IsInStackPtrCopySet(DefOp)) - return; -#endif + pair<STARSOpndTypePtr, STARS_ea_t> NewDefn(DefOp, InstAddr); // First, remove any definition of DefOp that precedes the current definition. set<pair<STARSOpndTypePtr, STARS_ea_t>, LessDefinition>::iterator DEDefnIter = this->GetFirstDownExposedDefn(); while (DEDefnIter != this->GetLastDownExposedDefn()) { STARSOpndTypePtr OldOp = DEDefnIter->first; if (IsEqOpIgnoreBitwidth(OldOp, DefOp)) { - (void) this->DownExposedDefnSet.erase(DEDefnIter); - break; // save time; should never be more than one defn per DefOp in this set, unlike ReachesIn & ReachesOut + STARS_ea_t OldAddr = DEDefnIter->second; + if (OldAddr == InstAddr) { // nothing is changing + return; + } + else { + (void) this->DownExposedDefnSet.erase(DEDefnIter); + this->SetReachesOutStale(); + break; // save time; should never be more than one defn per DefOp in this set, unlike ReachesIn & ReachesOut + } } else { ++DEDefnIter; } } + +#if 1 + // Only purpose of the DownExposedDefnSet is to track stack pointer copies, so save time. + if (!this->GetFunc()->IsDefnInStackPtrCopySet(DefOp, InstAddr)) + return; +#endif + // Next, insert the new definition. - pair<STARSOpndTypePtr, STARS_ea_t> NewDefn(DefOp, InstAddr); - pair<set<pair<STARSOpndTypePtr, STARS_ea_t>, LessDefinition>::iterator, bool> InsertResult; - InsertResult = this->DownExposedDefnSet.insert(NewDefn); + pair<set<pair<STARSOpndTypePtr, STARS_ea_t>, LessDefinition>::iterator, bool> InsertResult = this->DownExposedDefnSet.insert(NewDefn); assert(InsertResult.second); this->SetReachesOutStale(); return; diff --git a/src/base/SMPFunction.cpp b/src/base/SMPFunction.cpp index 6af059222ec75bcee666c6b637b06f004b55ed42..682f55fad1b2d8ed43b2c0c7c72ab985df7debb8 100644 --- a/src/base/SMPFunction.cpp +++ b/src/base/SMPFunction.cpp @@ -3722,6 +3722,35 @@ bool SMPFunction::IsInStackPtrCopySet(const STARSOpndTypePtr &CurrOp) { return found; } // end of SMPFunction::IsInStackPtrCopySet() +// Is definition CurrOp at DefAddr in the StackPtrCopySet, with any stack offset associated with it? +bool SMPFunction::IsDefnInStackPtrCopySet(const STARSOpndTypePtr &CurrOp, const STARS_ea_t &DefAddr) const { + if (nullptr == CurrOp) + return false; + + bool found = false; + // Set is composed of triples, so we have to iterate through it and compare operands. + set<pair<STARSOpndTypePtr, pair<STARS_ea_t, STARS_sval_t> >, LessStackDeltaCopy>::const_iterator CopyIter; + for (CopyIter = this->StackPtrCopySet.begin(); CopyIter != this->StackPtrCopySet.end(); ++CopyIter) { + pair<STARSOpndTypePtr, pair<STARS_ea_t, STARS_sval_t> > CurrCopy = *CopyIter; + STARSOpndTypePtr CopyOp = CurrCopy.first; + if (IsEqOp(CopyOp, CurrOp)) { + STARS_ea_t CopyAddr = CurrCopy.second.first; + if (CopyAddr == DefAddr) { + // Found it. + found = true; + break; + } + } + else if (CopyOp->GetOpType() > CurrOp->GetOpType()) { + // already moved past its spot; not found + break; + } + } + + return found; +} // end of SMPFunction::IsDefnInStackPtrCopySet() + + // Find evidence of calls to alloca(), which appear as stack space allocations (i.e. // subtractions [of unknown values(?)] from the stack pointer) AFTER the local frame allocation instruction // for this function.