diff --git a/ProfilerInformation.cpp b/ProfilerInformation.cpp index f8e7b7e28880f9235b6edc6a6f42e89806be0cda..70055afbed345d0a5c62d380666cc19362a40074 100644 --- a/ProfilerInformation.cpp +++ b/ProfilerInformation.cpp @@ -188,6 +188,10 @@ ProfilerInformation::ProfilerInformation(const char* fn, SMPProgram *CurrProg) /* profiler generated information */ addProfileInformation(addr, 0, 0, atoll(scope)); } + else if (strcmp(type, "BLOCK") == 0) + { + ; // not processing BLOCK profiling annotation yet + } else { msg("ERROR: Unknown annotation type '%s' near line %d\n", type, line); diff --git a/SMPBasicBlock.h b/SMPBasicBlock.h index 712901c90da78dbf95092285fd0eac2a221665b2..9d714da5a289dbce1b46500d0d3c47b730228565 100644 --- a/SMPBasicBlock.h +++ b/SMPBasicBlock.h @@ -84,6 +84,8 @@ public: inline void SetNumber(int Num) { BlockNum = Num; }; void LinkToPred(list<SMPBasicBlock>::iterator Predecessor); void LinkToSucc(list<SMPBasicBlock>::iterator Successor); + inline void AddLiveIn(op_t LiveOp) { LiveInSet.insert(LiveOp); return; }; + inline void AddLiveOut(op_t LiveOp) { LiveOutSet.insert(LiveOp); return; }; inline void AddVarKill(op_t KillOp) { KillSet.insert(KillOp); return; }; bool ErasePhi(op_t OldOp); // erase() from phi function list void ErasePred(ea_t FirstAddr); // erase() block starting at FirstAddr from Preds list diff --git a/SMPFunction.cpp b/SMPFunction.cpp index 6bd9e54d3c918c51816cbae54977c11c4137f82c..ec052417fe71a1e824be418998c7ebc68096c4a6 100644 --- a/SMPFunction.cpp +++ b/SMPFunction.cpp @@ -49,6 +49,7 @@ #define SMP_DEBUG_UNINITIALIZED_SSA_NAMES 1 #define SMP_WARN_UNUSED_DEFS 0 #define SMP_DEBUG_SWITCH_TABLE_INFO 0 +#define SMP_OPTIMIZE_BLOCK_PROFILING 0 // Compute LVA/SSA or not? Turn it off for NICECAP demo on 31-JAN-2008 #define SMP_COMPUTE_LVA_SSA 1 @@ -144,6 +145,9 @@ SMPFunction::SMPFunction(func_t *Info, SMPProgram* pgm) { this->SSAStack.clear(); this->LocalVarTable.clear(); this->StackFrameMap.clear(); + this->LiveInSet.clear(); + this->LiveOutSet.clear(); + this->KillSet.clear(); this->ReturnRegTypes.clear(); this->SavedRegLoc.clear(); @@ -164,6 +168,36 @@ void SMPFunction::ResetProcessedBlocks(void) { return; } // end of SMPFunction::ResetProcessedBlocks() +// Return an iterator for the beginning of the LiveInSet. +set<op_t, LessOp>::iterator SMPFunction::GetFirstLiveIn(void) { + return this->LiveInSet.begin(); +} // end of SMPBasicBlock::GetFirstLiveIn() + +// Get termination iterator marker for the LiveIn set, for use by predecessors. +set<op_t, LessOp>::iterator SMPFunction::GetLastLiveIn(void) { + return this->LiveInSet.end(); +} + +// Get iterator for the start of the LiveOut set. +set<op_t, LessOp>::iterator SMPFunction::GetFirstLiveOut(void) { + return this->LiveOutSet.begin(); +} + +// Get termination iterator marker for the LiveOut set. +set<op_t, LessOp>::iterator SMPFunction::GetLastLiveOut(void) { + return this->LiveOutSet.end(); +} + +// Get iterator for the start of the VarKill set. +set<op_t, LessOp>::iterator SMPFunction::GetFirstVarKill(void) { + return this->KillSet.begin(); +} + +// Get termination iterator marker for the VarKill set. +set<op_t, LessOp>::iterator SMPFunction::GetLastVarKill(void) { + return this->KillSet.end(); +} + // Add a caller to the list of all callers of this function. void SMPFunction::AddCallSource(ea_t addr) { // Convert call instruction address to beginning address of the caller. @@ -2588,8 +2622,9 @@ void SMPFunction::LiveVariableAnalysis(void) { ++UpExposedIter) { // Add DEF with SSANum of 0. MarkerInst->AddDef(*UpExposedIter, UNINIT, 0); - // Add to the VarKill set. + // Add to the VarKill and LiveIn sets. this->Blocks.begin()->AddVarKill(*UpExposedIter); + this->Blocks.begin()->AddLiveIn(*UpExposedIter); } for (LiveOutIter = this->Blocks.begin()->GetFirstLiveOut(); LiveOutIter != this->Blocks.begin()->GetLastLiveOut(); @@ -2597,8 +2632,9 @@ void SMPFunction::LiveVariableAnalysis(void) { if (!(this->Blocks.begin()->IsVarKill(*LiveOutIter))) { // Add DEF with SSANum of 0. MarkerInst->AddDef(*LiveOutIter, UNINIT, 0); - // Add to the VarKill set. + // Add to the VarKill and LiveIn sets. this->Blocks.begin()->AddVarKill(*LiveOutIter); + this->Blocks.begin()->AddLiveIn(*LiveOutIter); } } #endif @@ -3859,11 +3895,13 @@ void SMPFunction::EmitAnnotations(FILE *AnnotFile) { for (CurrBlock = this->Blocks.begin(); CurrBlock != this->Blocks.end(); ++CurrBlock) { if (CurrBlock->MaybeAliasedWrite()) { ++(this->UnsafeBlocks); +#if SMP_OPTIMIZE_BLOCK_PROFILING list<list<SMPInstr>::iterator>::iterator CurrInst; CurrInst = CurrBlock->GetFirstInstr(); ea_t addr = (*CurrInst)->GetAddr(); qfprintf(AnnotFile, "%10x %6d BLOCK PROFILECOUNT %s\n", addr, (*CurrInst)->GetCmd().size, (*CurrInst)->GetDisasm()); +#endif } else { ++(this->SafeBlocks); diff --git a/SMPFunction.h b/SMPFunction.h index e875f8ef380ed1aac91507df144c5c60a7717501..51bef3787018b381e4f04475d67221eb7eb06e16 100644 --- a/SMPFunction.h +++ b/SMPFunction.h @@ -74,6 +74,12 @@ public: inline set<op_t, LessOp>::iterator GetLastGlobalName(void) { return GlobalNames.end(); }; inline size_t NumGlobalNames(void) { return GlobalNames.size(); }; inline set<op_t, LessOp>::iterator FindGlobalName(op_t SearchOp) { return GlobalNames.find(SearchOp); }; + set<op_t, LessOp>::iterator GetFirstLiveIn(void); // LiveInSet.begin() + set<op_t, LessOp>::iterator GetLastLiveIn(void); // LiveInSet.end() + set<op_t, LessOp>::iterator GetFirstLiveOut(void); // LiveOutSet.begin() + set<op_t, LessOp>::iterator GetLastLiveOut(void); // LiveOutSet.end() + set<op_t, LessOp>::iterator GetFirstVarKill(void); // KillSet.begin() + set<op_t, LessOp>::iterator GetLastVarKill(void); // KillSet.end() inline FuncType GetReturnAddressStatus(void) const { return ReturnAddrStatus;} inline const ea_t GetStartAddr() const { return FuncInfo.startEA; }; // exposing the start address of the function. Used in RecurseAndMark inline const vector<ea_t> GetCallTargets() const { return AllCallTargets; }; @@ -113,12 +119,22 @@ public: inline bool WritesAboveReturnAddress(void) const { return WritesAboveRA; }; inline bool IsGlobalName(op_t RefOp) const { return (GlobalNames.end() != GlobalNames.find(RefOp)); }; inline bool UsesFramePointer(void) const { return UseFP; }; + inline bool IsLiveIn(op_t CurrOp) const { + return (LiveInSet.end() != LiveInSet.find(CurrOp)); + } + inline bool IsLiveOut(op_t CurrOp) const { + return (LiveOutSet.end() != LiveOutSet.find(CurrOp)); + } + inline bool IsVarKill(op_t CurrOp) const { + return (KillSet.end() != KillSet.find(CurrOp)); + } // Printing methods void Dump(void); // debug dump // Analysis methods void ResetProcessedBlocks(void); // Set Processed flag to false in all blocks + bool ComputeGlobalSets(void); // return true if LiveIn, LiveOut, Kill sets change void Analyze(void); // Analyze all instructions in function void EmitAnnotations(FILE *AnnotFile); void RPONumberBlocks(void); @@ -199,6 +215,11 @@ private: vector<int> SavedRegLoc; // indexed by reg #; offset from return address of callee-saved reg vector<SMPOperandType> ReturnRegTypes; // indexed by reg #; inferred types upon return + // Four sets used in live variable analysis + set<op_t, LessOp> KillSet; // registers killed in this function + set<op_t, LessOp> LiveOutSet; // Live-Out registers in this function + set<op_t, LessOp> LiveInSet; // registers live in to this function + // Methods void SetStackFrameInfo(void); ea_t FindAllocPoint(asize_t); // Deal with difficult to find stack frame allocations diff --git a/SMPProgram.cpp b/SMPProgram.cpp index 0cd03075416bd1944b45bb7c4bcf68a2923ed595..ae541f73493c86f9c0bcd161193d18419a14aae3 100644 --- a/SMPProgram.cpp +++ b/SMPProgram.cpp @@ -337,7 +337,11 @@ void SMPProgram::Analyze(ProfilerInformation *pi) { } // end if SEG_CODE segment } // end for all segments - map<ea_t, SMPFunction *>::iterator MapIter; +#if 0 + this->ComputeGlobalSets(); +#endif + + map<ea_t, SMPFunction*>::iterator MapIter; for (MapIter = this->FuncMap.begin(); MapIter != this->FuncMap.end(); ++MapIter) { CurrFunc = MapIter->second; if (NULL == CurrFunc) { diff --git a/SMPProgram.h b/SMPProgram.h index 8162c098f3c05c086d064e2956ff1a24b74fc6b2..b362b3794968e1a7b13d3fbcd2ff71d20ecf9eb5 100644 --- a/SMPProgram.h +++ b/SMPProgram.h @@ -106,6 +106,7 @@ private: // Methods void InitStaticDataTable(void); // Gather info about global static data locations void ComputeGlobalFieldOffsets(struct GlobalVar &CurrGlobal); + void ComputeGlobalSets(void); // LiveIn, LiveOut, VarKill for each func FuncType RecurseAndMarkRetAdd(SMPFunction *); }; // end class SMPProgram