Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • opensrc/SMPStaticAnalyzer
1 result
Show changes
Commits on Source (3)
*.swp
*.o
*.os
scons_build
......
......@@ -229,6 +229,12 @@ void DumpInductionVar(const struct InductionVarTriple IndVar);
// Debug dump of InductionVarFamily.
void DumpInductionVarFamily(const struct InductionVarFamily IVFamily);
// Emit annotation for induction variable.
void EmitInductionVarAnnotation(const struct InductionVarTriple IndVar);
// Emit annotations for InductionVarFamily.
void EmitInductionVarFamilyAnnotations(const struct InductionVarFamily IVFamily);
// Determine whether we have an incrementing or decrementing loop based on
// the BasicInductionVar.
bool IsPositiveIncrementBIV(const struct InductionVarTriple BIV);
......@@ -252,6 +258,7 @@ public:
};
STARS_Function_t *GetFuncInfo(void) const;
inline STARS_ea_t GetFirstFuncAddr(void) const { return FirstEA; };
inline STARS_ea_t GetFuncID(void) const { return FuncInfo->getFuncID(); };
uint16_t GetJumpToFollowNodeCounter(STARS_ea_t InstAddr) const;
inline long GetTypedDefs(void) const { return TypedDefs; };
inline long GetUntypedDefs(void) const { return UntypedDefs; };
......@@ -757,6 +764,7 @@ private:
std::vector<struct FineGrainedInfo> ReturnRegFGInfo; // indexed by reg #; inferred FG info upon return
std::vector<STARSBitSet> FuncLoopsByBlock; // vector indexed by block number, bitset indexed by loop number, set bit means block # is in loop #
std::vector<STARSBitSet> FuncBlocksByLoop; // vector indexed by loop number, bitset indexed by block number, set bit means loop includes block #
std::vector<STARSBitSet> LoopNests; // vector indexed by outer loop number, bitset indexed by inner loop number, set bit means outer loop includes inner loop
std::vector<STARSBitSet> PositiveOffsetStackBytesWrittenByLoop; // vector indexed by loop number, bitset indexed by byte offset from incoming stack pointer, set bit means memory byte written
std::vector<STARSBitSet> NegativeOffsetStackBytesWrittenByLoop; // vector indexed by loop number, bitset indexed by byte offset from minimum stack pointer value, set bit means memory byte written
std::vector<int> LoopTypesByLoopNum; // indexed by loop number: top-testing, bottom-testing, middle-testing or infinite
......@@ -939,7 +947,10 @@ private:
bool IsBlockNumLoopHeader(const int BlockNum, std::size_t &LoopNum) const; // Is BlockNum already in this->LoopHeadBlockNumbers? If so, put index in LoopNum
void FindLoopBlocksFromTailToHeader(const std::size_t LoopNumber, const int HeadBlockNum, std::list<SMPBasicBlock *>::iterator BlockIter, int &DoubleTailFollowBlockNum); // populate FuncLoopsByBlock and FuncBlocksByLoop data structures for DetectLoops()
void DetectLoops(void); // Detect which blocks are in which loops and populate FuncLoopsByBlock and FuncBlocksByLoop data structures.
void DetectLoopFollowBlock(const size_t LoopNumber); // Detect successor blocks not in loop; if not exactly one, not structured CFG.
void ComputeLoopNests(void); // fill LoopNests data structure.
void EmitLoopNestAnnotations(void); // Emit info on loop nesting and preheader blocks.
int FindLoopPreheaderBlockNum(std::size_t LoopIndex) const; // return -1 if no preheader (immediate predecessor that dominates header, has only 1 successor)
void DetectLoopFollowBlock(const std::size_t LoopNumber); // Detect successor blocks not in loop; if not exactly one, not structured CFG.
void ClassifyLoop(std::size_t LoopNumber, int HeaderExitFollowNum, int TailExitFollowNum, SMPBasicBlock *CurrBlock, SMPBasicBlock *HeadBlock, bool HeaderBlockExitsLoop, bool TailBlockExitsLoop); // classify LoopNumber loop as top, middle, or bottom testing
bool DoesBlockExitLoop(std::size_t LoopNumber, SMPBasicBlock *LoopBlock, int &FollowBlockNum); // return true if block can exit the loop.
void DetectLoopInvariantDEFs(void); // Collect a set of loop-invariant DEFs with the inst IDs of the DEFs.
......
......@@ -12,6 +12,7 @@ class STARS_Function_t
virtual char* GetFunctionName(char* name, const int len) const = 0;
virtual STARS_ea_t get_startEA() = 0;
virtual STARS_ea_t get_endEA() = 0;
virtual STARS_ea_t getFuncID(void) const = 0;
virtual std::size_t GetFuncSize() = 0;
virtual std::size_t GetFrameSize() = 0;
virtual void SetFrameSize(std::size_t size) = 0;
......
......@@ -61,6 +61,7 @@ class STARS_Program_t
FILE *GetXrefsFile(void) const { return STARS_XrefsFile; };
FILE *GetCallReturnFile(void) const { return STARS_CallReturnFile; };
FILE *GetUninitVarFile(void) const { return STARS_UninitVarFile; };
FILE *GetLoopsAnnotFile(void) const { return STARS_LoopsAnnotFile; };
FILE *GetSPARKHeaderFile(void) const { return ZST_SPARKHeaderFile; };
FILE *GetSPARKSourceFile(void) const { return ZST_SPARKSourceFile; };
std::list<STARS_regnum_t>::iterator GetFirstCallerSavedReg(void) { return STARS_MDCallerSavedRegs.begin(); };
......@@ -250,6 +251,9 @@ class STARS_Program_t
// File for uninitialized variables detected.
FILE *STARS_UninitVarFile;
// File for annotations describing loops and induction variables.
FILE *STARS_LoopsAnnotFile;
// Files for SPARK Ada translation of program RTLs
FILE *ZST_SPARKSourceFile;
FILE *ZST_SPARKHeaderFile;
......
......@@ -27,9 +27,10 @@ public:
virtual STARS_ea_t get_startEA() { return the_func->startEA; }
virtual STARS_ea_t get_endEA() { return the_func->endEA; }
#else
virtual STARS_ea_t get_startEA() { return the_func->start_ea; }
virtual STARS_ea_t get_endEA() { return the_func->end_ea; }
virtual STARS_ea_t get_startEA() { return the_func->start_ea; }
virtual STARS_ea_t get_endEA() { return the_func->end_ea; }
#endif
virtual STARS_ea_t getFuncID(void) const { return the_func->start_ea; };
virtual std::size_t GetFuncSize() { return (std::size_t) (get_endEA() - get_startEA()); }
virtual char* GetFunctionName(char* name, const int len) const {
qstring TempName;
......
......@@ -21,10 +21,12 @@ public:
{ strncpy((char*)name,the_func->getName().c_str(),len); return (char*)name; }
// get entry point of function
virtual STARS_ea_t get_startEA() { return the_func->getEntryPoint()->getBaseID(); }
virtual STARS_ea_t get_startEA() { return the_func->getEntryPoint()->getBaseID(); }
// clc needs to review and get back to me.
virtual STARS_ea_t get_endEA() { assert(0); }
virtual STARS_ea_t get_endEA() { assert(0); }
virtual STARS_ea_t getFuncID(void) const { return (STARS_ea_t) the_func->getBaseID(); };
// return # of instructions.
virtual std::size_t GetFuncSize() { return the_func->getInstructions().size(); }
......@@ -34,7 +36,7 @@ public:
//This chunk of things is going away?
// init class-local variable with IRDB value
// and these are accessors to that.
virtual std::size_t GetFrameSize(){ return the_func -> getStackFrameSize(); }
virtual std::size_t GetFrameSize(){ return the_func->getStackFrameSize(); }
// should go away.
......
......@@ -190,6 +190,17 @@ void DumpInductionVarFamily(const struct InductionVarFamily IVFamily) {
}
} // end of DumpInductionVarFamily()
 
// Emit annotation for induction variable.
void EmitInductionVarAnnotation(const struct InductionVarTriple IndVar) {
return;
}
// Emit annotations for InductionVarFamily.
void EmitInductionVarFamilyAnnotations(const struct InductionVarFamily IVFamily) {
return;
}
// Determine whether we have an incrementing or decrementing loop based on
// the BasicInductionVar.
bool IsPositiveIncrementBIV(const struct InductionVarTriple BIV) {
......@@ -6553,6 +6564,7 @@ void SMPFunction::RecomputeSSA(void) {
this->LoopTypesByLoopNum.clear();
this->FuncLoopsByBlock.clear();
this->FuncBlocksByLoop.clear();
this->LoopNests.clear();
this->GlobalDefAddrBySSA.clear();
this->LoopInductionVars.clear();
#if 1 // need to debug
......@@ -6644,8 +6656,10 @@ void SMPFunction::ComputeSSA(void) {
}
 
this->FuncBlocksByLoop.resize(this->LoopCount);
this->LoopNests.resize(this->LoopCount);
for (size_t LoopIndex = 0; LoopIndex < this->LoopCount; ++LoopIndex) {
this->FuncBlocksByLoop.at(LoopIndex).AllocateBits(this->BlockCount);
this->LoopNests.at(LoopIndex).AllocateBits(this->LoopCount);
}
this->LoopTypesByLoopNum.resize(this->LoopCount);
this->LoopTestBlocksByLoopNum.resize(this->LoopCount);
......@@ -6674,6 +6688,12 @@ void SMPFunction::ComputeSSA(void) {
this->Dump();
#endif
 
// Compute the loop nests.
this->ComputeLoopNests();
// Emit loop nest annotations.
this->EmitLoopNestAnnotations();
// Once SSA numbers have been set into all DEFs, USES, and DU-chains, then
// the SSA numbering data structures will no longer be used and can be
// de-allocated.
......@@ -6967,6 +6987,87 @@ void SMPFunction::DetectLoops(void) {
return;
} // end of SMPFunction::DetectLoops()
 
// fill LoopNests data structure.
void SMPFunction::ComputeLoopNests(void) {
// A loop contains another loop if the header block of the first loop
// dominates the header block of the second loop.
for (size_t LoopIndex1 = 0; LoopIndex1 < this->LoopCount; ++LoopIndex1) {
for (size_t LoopIndex2 = 0; LoopIndex2 < this->LoopCount; ++LoopIndex2) {
if (LoopIndex1 != LoopIndex2) {
int HeaderBlock1 = this->LoopHeadBlockNumbers[LoopIndex1];
int HeaderBlock2 = this->LoopHeadBlockNumbers[LoopIndex2];
if (this->DoesBlockDominateBlock(HeaderBlock1, HeaderBlock2)) {
// Loop 2 is nested inside loop 1.
this->LoopNests[LoopIndex1].SetBit(LoopIndex2);
}
}
}
}
return;
}
// Emit info on loop nesting and preheader blocks.
// Annotations look like:
// [hex func ID] [func size] LOOP [loop #] FIRSTINST [hex inst ID at beginning of loop header] PREHEADER [hex inst ID] BLOCKLIST [hex inst IDs] ZZ INNERLOOPS [loop #'s] ZZ
void SMPFunction::EmitLoopNestAnnotations(void) {
if (0 < this->LoopCount) {
FILE *LoopAnnotFile = global_STARS_program->GetLoopsAnnotFile();
SMP_fprintf(LoopAnnotFile, "%18llx %6zu LOOPCOUNT %zu \n", (uint64_t) this->GetFuncID(), this->FuncInfo->GetFuncSize(), this->LoopCount);
for (size_t LoopIndex = 0; LoopIndex < this->LoopCount; ++LoopIndex) {
int HeaderBlockNum = this->LoopHeadBlockNumbers[LoopIndex];
SMPBasicBlock *HeaderBlock = this->GetBlockByNum((size_t) HeaderBlockNum);
STARS_ea_t FirstHeaderInstAddr = HeaderBlock->GetFirstNonMarkerAddr();
int PreheaderBlockNum = this->FindLoopPreheaderBlockNum(LoopIndex);
STARS_ea_t PreheaderFirstInstAddr = STARS_BADADDR;
if (PreheaderBlockNum >= 0) {
PreheaderFirstInstAddr = this->GetBlockByNum(PreheaderBlockNum)->GetFirstNonMarkerAddr();
}
SMP_fprintf(LoopAnnotFile, "%18llx %6zu LOOP %zu FIRSTINST %18llx PREHEADER %18llx BLOCKLIST ",
(uint64_t) this->GetFuncID(), this->FuncInfo->GetFuncSize(), LoopIndex, (uint64_t) FirstHeaderInstAddr, (uint64_t) PreheaderFirstInstAddr);
// Emit the first inst ID for each block in the loop.
list<size_t> LoopBlockList;
this->BuildLoopBlockList(LoopIndex, LoopBlockList);
for (size_t BlockNum : LoopBlockList) {
SMP_fprintf(LoopAnnotFile, "%18llx ", (uint64_t) this->GetBlockByNum(BlockNum)->GetFirstNonMarkerAddr());
}
SMP_fprintf(LoopAnnotFile, "ZZ INNERLOOPS ");
// Emit the loop indices for inner loops.
for (size_t LoopIndex2 = 0; LoopIndex2 < this->LoopCount; ++LoopIndex2) {
if (this->LoopNests[LoopIndex].GetBit(LoopIndex2)) {
SMP_fprintf(LoopAnnotFile, "%zu ", LoopIndex2);
}
}
SMP_fprintf(LoopAnnotFile, "ZZ \n");
}
}
return;
}
// return -1 if no preheader (immediate predecessor that dominates header, has only header as successor)
int SMPFunction::FindLoopPreheaderBlockNum(size_t LoopIndex) const {
int PreheaderBlockNum = SMP_BLOCKNUM_UNINIT;
assert(LoopIndex < this->LoopCount);
int HeaderBlockNum = this->LoopHeadBlockNumbers[LoopIndex];
assert(0 <= HeaderBlockNum);
SMPBasicBlock *HeaderBlock = this->GetBlockByNum((size_t) HeaderBlockNum);
for (list<SMPBasicBlock *>::const_iterator PredIter = HeaderBlock->GetFirstConstPred();
PredIter != HeaderBlock->GetLastConstPred();
++PredIter) {
SMPBasicBlock *PredBlock = (*PredIter);
if (1 == PredBlock->GetNumSuccessors()) {
if (this->DoesBlockDominateBlock(PredBlock->GetNumber(), HeaderBlockNum)) {
PreheaderBlockNum = PredBlock->GetNumber();
break;
}
}
}
return PreheaderBlockNum;
} // end of SMPFunction::FindLoopPreheaderBlockNum()
void SMPFunction::DetectLoopFollowBlock(const size_t LoopNumber) {
list<size_t> LoopBlockNums;
this->BuildLoopBlockList(LoopNumber, LoopBlockNums);
......
......@@ -215,6 +215,7 @@ int STARS::IRDB_Interface_t::do_STARS(FileIR_t* firp)
// now re-read them with a meds annotation parser
parser.parseFile(gsp->GetAnnotFileName());
parser.parseFile(gsp->GetInfoAnnotFileName());
parser.parseFile(gsp->GetRootFileName()+".STARSloops");
// cleanup memory allocated by driver.
delete profinfo;
......
......@@ -148,6 +148,10 @@ bool STARS_Program_t::OpenSecondaryFilesOnly(void) {
string UninitVarFileName(this->GetRootFileName());
string UninitVarFileSuffix(".STARSuninit");
UninitVarFileName += UninitVarFileSuffix;
string LoopsFileName(this->GetRootFileName());
string LoopsFileSuffix(".STARSloops");
LoopsFileName += LoopsFileSuffix;
string SPARKSourceFileName("");
string SPARKHeaderFileName("");
if (global_STARS_program->ShouldSTARSTranslateToSPARKAda()) {
......@@ -211,6 +215,17 @@ bool STARS_Program_t::OpenSecondaryFilesOnly(void) {
return false;
}
this->STARS_LoopsAnnotFile = SMP_fopen(LoopsFileName.c_str(), "w");
if (NULL == this->STARS_LoopsAnnotFile) {
SMP_msg("FATAL ERROR: Cannot open loops annotations file %s\n", LoopsFileName.c_str());
(void)SMP_fclose(this->STARS_XrefsFile);
(void)SMP_fclose(this->STARS_CallReturnFile);
(void)SMP_fclose(this->STARS_UninitVarFile);
(void)SMP_fclose(this->ZST_AlarmFile);
(void)SMP_fclose(this->STARS_InfoAnnotFile);
return false;
}
if (global_STARS_program->ShouldSTARSTranslateToSPARKAda()) {
this->ZST_SPARKSourceFile = SMP_fopen(SPARKSourceFileName.c_str(), "w");
if (NULL == this->ZST_SPARKSourceFile) {
......@@ -220,6 +235,7 @@ bool STARS_Program_t::OpenSecondaryFilesOnly(void) {
(void)SMP_fclose(this->STARS_UninitVarFile);
(void)SMP_fclose(this->ZST_AlarmFile);
(void)SMP_fclose(this->STARS_InfoAnnotFile);
(void)SMP_fclose(this->STARS_LoopsAnnotFile);
return false;
}
this->ZST_SPARKHeaderFile = SMP_fopen(SPARKHeaderFileName.c_str(), "w");
......@@ -230,6 +246,7 @@ bool STARS_Program_t::OpenSecondaryFilesOnly(void) {
(void)SMP_fclose(this->STARS_UninitVarFile);
(void)SMP_fclose(this->ZST_AlarmFile);
(void)SMP_fclose(this->STARS_InfoAnnotFile);
(void)SMP_fclose(this->STARS_LoopsAnnotFile);
(void)SMP_fclose(this->ZST_SPARKSourceFile);
return false;
}
......@@ -251,6 +268,7 @@ void STARS_Program_t::CloseFiles(void) {
(void) SMP_fclose(this->STARS_CallReturnFile);
(void) SMP_fclose(this->STARS_XrefsFile);
(void) SMP_fclose(this->STARS_UninitVarFile);
(void) SMP_fclose(this->GetLoopsAnnotFile());
return;
} // end of STARS_Program_t::CloseFiles()
......