From 0c9e73fd72db0239430370e209ab734b78ed4c77 Mon Sep 17 00:00:00 2001 From: clc5q <clc5q@git.zephyr-software.com> Date: Fri, 4 Dec 2015 17:43:05 +0000 Subject: [PATCH] Fixes and cleanups for SPARK Ada translation. Former-commit-id: 1e20c1306f474f69e082dbe7ee97644df311a360 --- include/base/SMPDataFlowAnalysis.h | 5 +- include/base/SMPFunction.h | 2 +- src/base/SMPDataFlowAnalysis.cpp | 50 +++++++++++++++++++ src/base/SMPFunction.cpp | 80 +++++++++++++++++------------- src/base/SMPInstr.cpp | 10 +++- src/base/SMPProgram.cpp | 2 +- 6 files changed, 111 insertions(+), 38 deletions(-) diff --git a/include/base/SMPDataFlowAnalysis.h b/include/base/SMPDataFlowAnalysis.h index 9d154a7f..97dcef60 100644 --- a/include/base/SMPDataFlowAnalysis.h +++ b/include/base/SMPDataFlowAnalysis.h @@ -983,7 +983,10 @@ unsigned int CountBitsSet(unsigned int ArgPosBits); // Utility to get highest bit set in a byte. unsigned int HighestBitSet(unsigned char Byte); -// Is FuncName a standard library function name? +// Is CalleeName a standard library function name? bool IsLibFuncName(std::string CalleeName); +// Is FuncName a startup func called before main(), or a wrapup function called by the system? +bool IsStartupFuncName(const std::string FuncName); + #endif diff --git a/include/base/SMPFunction.h b/include/base/SMPFunction.h index 7d571923..20314964 100644 --- a/include/base/SMPFunction.h +++ b/include/base/SMPFunction.h @@ -626,7 +626,7 @@ private: void UpdateLoopFollowBlockNum(int HeaderBlockNum, int FollowBlockNum); int GetLoopNumFromHeaderBlockNum(const int HeaderBlockNum) const; // return -1 if HeaderBlockNum is not a loop header block # std::size_t FindLoopNumFromHeadBlockNum(int LoopHeaderBlockNum) const; // find loop # corresponding to header block num - int FindFollowBlockNum(SMPBasicBlock *CurrBlock); // Based on control flow structure of CurrBlock, find Ada follow block num; -1 if no structure besides fall-through + int FindFollowBlockNum(SMPBasicBlock *CurrBlock, bool StartAtLastInst = false); // Based on control flow structure of CurrBlock, find Ada follow block num; -1 if no structure besides fall-through bool AnalyzeSwitchStatement(SMPBasicBlock *CurrBlock); // Analyze switch starting at indir jump at end of CurrBlock; return false if not well-structured void FindSwitchIDom(struct SwitchTableInfo &TableInfo); // Mark jumps to default case, find IDom of entire switch statement bool AnalyzeConditionalStatements(void); // Analyze if-then-elses starting at COND_BRANCH at end of all blocks; return false if not well-structured diff --git a/src/base/SMPDataFlowAnalysis.cpp b/src/base/SMPDataFlowAnalysis.cpp index ffacb4a7..719e0b6e 100644 --- a/src/base/SMPDataFlowAnalysis.cpp +++ b/src/base/SMPDataFlowAnalysis.cpp @@ -4267,3 +4267,53 @@ bool IsLibFuncName(std::string CalleeName) { return false; } // end of IsLibFuncName() + +// Is FuncName a startup func called before main(), or a wrapup function called by the system? +bool IsStartupFuncName(const std::string FuncName) { + bool NameMatched = false; + char IDA_func_name[STARS_MAXSTR]; + std::size_t SkipCount; + + SkipCount = strspn(FuncName.c_str(), "._"); + std::string TempFuncName = FuncName.substr(SkipCount); // remove leading periods and underscores + + if (0 == TempFuncName.compare("init_proc")) { + NameMatched = true; + } + else if (0 == TempFuncName.compare("init")) { + NameMatched = true; + } + else if (0 == TempFuncName.compare("start")) { + NameMatched = true; + } + else if (0 == TempFuncName.compare("gmon_start")) { + NameMatched = true; + } + else if (0 == TempFuncName.compare("call_gmon_start")) { + NameMatched = true; + } + else if (0 == TempFuncName.compare("libc_start_main")) { + NameMatched = true; + } + else if (0 == TempFuncName.compare("call_gmon_start__")) { + NameMatched = true; + } + else if (0 == TempFuncName.compare("libc_start_main__")) { + NameMatched = true; + } + else if (0 == TempFuncName.compare("libc_csu_init")) { + NameMatched = true; + } + else if (0 == TempFuncName.compare("libc_csu_fini")) { + NameMatched = true; + } + else if (0 == TempFuncName.compare("do_global_dtors_aux")) { + NameMatched = true; + } + else if (0 == TempFuncName.compare("term_proc")) { + NameMatched = true; + } + + + return NameMatched; +} diff --git a/src/base/SMPFunction.cpp b/src/base/SMPFunction.cpp index 36005472..0eadc8e8 100644 --- a/src/base/SMPFunction.cpp +++ b/src/base/SMPFunction.cpp @@ -82,6 +82,9 @@ using namespace std; #define STARS_DEBUG_FUNC_SCCP 0 #define STARS_DEBUG_LOOP_INVARIANTS 1 +// For debugging purposes, only emit SPARK Ada for main(). +#define STARS_EMIT_ADA_FOR_MAIN_ONLY 0 + // Compute LVA/SSA or not? Turn it off for NICECAP demo on 31-JAN-2008 #define SMP_COMPUTE_LVA_SSA 1 @@ -8568,7 +8571,7 @@ void SMPFunction::MarkSpecialNumericErrorCases(void) { if ((this->LoopCount > 0) && this->HasReducibleControlFlow() && (!this->HasUnresolvedIndirectJumps())) { #endif list<SMPInstr *>::iterator InstIter; - for (InstIter = this->Instrs.begin(); InstIter != this->Instrs.end(); ++InstIter) { + for (InstIter = this->Instrs.begin(); InstIter != this->Instrs.end(); ++InstIter) { // !!!!****!!!! loop through blocks !! CurrInst = (*InstIter); STARS_ea_t InstAddr = CurrInst->GetAddr(); SMPitype CurrDataFlowType = CurrInst->GetDataFlowType(); @@ -9586,9 +9589,6 @@ void SMPFunction::PreProcessForSPARKAdaTranslation(void) { return; } // end of SMPFunction::PreProcessForSPARKAdaTranslation() -// For debugging purposes, only emit SPARK Ada for main(). -#define STARS_EMIT_ADA_FOR_MAIN_ONLY 1 - // Emit SPARK Ada translation of function void SMPFunction::EmitFuncSPARKAda(void) { if (this->IsLinkerStub()) { @@ -9601,6 +9601,9 @@ void SMPFunction::EmitFuncSPARKAda(void) { return; } #endif + if (IsStartupFuncName(AdaFuncName)) { + return; + } // Convert dashes to underscores in the func name to suit Ada standards. replace(AdaFuncName.begin(), AdaFuncName.end(), '-', '_'); @@ -9725,8 +9728,8 @@ void SMPFunction::EmitFuncSPARKAda(void) { this->EmitSPARKAdaForBlock(0, FollowBlockNum, BodyFile); #endif - SMP_fprintf(BodyFile, "\nend %s;\n", AdaFuncName.c_str()); - STARS_SPARK_IndentCount = 0; + SMP_fprintf(BodyFile, "\nend %s;\n\n", AdaFuncName.c_str()); + STARS_SPARK_IndentCount = 1; return; } // end of SMPFunction::EmitFuncSPARKAda() @@ -9774,7 +9777,7 @@ void SMPFunction::EmitSPARKAdaForBlock(int CurrBlockNum, int FollowBlockNum, FIL ControlFlowType LastCFType = this->GetControlFlowType(LastAddr); if (FlowType == INDIR_JUMP) { // Translate switch-case statement. - int NextFollowBlockNum = this->FindFollowBlockNum(CurrBlock); + int NextFollowBlockNum = this->FindFollowBlockNum(CurrBlock, true); this->EmitSPARKAdaForSwitch(CurrBlockNum, NextFollowBlockNum, SPARKBodyFile); ResumeBlockNum = NextFollowBlockNum; } @@ -9808,7 +9811,7 @@ void SMPFunction::EmitSPARKAdaForBlock(int CurrBlockNum, int FollowBlockNum, FIL else { assert((LastCFType == BRANCH_IF_THEN) || (LastCFType == BRANCH_IF_THEN_ELSE)); // Translate if-else structure previously identified - int NextFollowBlockNum = this->FindFollowBlockNum(CurrBlock); + int NextFollowBlockNum = this->FindFollowBlockNum(CurrBlock, true); LastInst->EmitSPARKAda(SPARKBodyFile); // emit if (inverted condition) then this->EmitSPARKAdaForConditional(CurrBlockNum, NextFollowBlockNum, SPARKBodyFile); ResumeBlockNum = NextFollowBlockNum; @@ -9848,7 +9851,7 @@ void SMPFunction::EmitSPARKAdaForBlock(int CurrBlockNum, int FollowBlockNum, FIL else { // Last inst was translated by SMPBasicBlock::EmitSPARKAdaForFallThroughInsts(). // CurrBlock can only have one successor, a fall-through block. - // NOTE: If CurrBlock ends with a call to a NORET function, we can have no successors. + // NOTE: If CurrBlock ends with a HALT or a call to a NORET function, we can have no successors. size_t NumSuccessors = CurrBlock->GetNumSuccessors(); if (1 == NumSuccessors) { SMPBasicBlock *FallThroughSucc = (*(CurrBlock->GetFirstSucc())); @@ -9856,7 +9859,7 @@ void SMPFunction::EmitSPARKAdaForBlock(int CurrBlockNum, int FollowBlockNum, FIL ResumeBlockNum = FallThroughSucc->GetNumber(); } else { - assert((FlowType == CALL) && (0 == NumSuccessors)); + assert(((FlowType == CALL) || (FlowType == HALT)) && (0 == NumSuccessors)); } } } // end if header block ... elsif tail block ... else ... @@ -9907,13 +9910,13 @@ void SMPFunction::EmitSPARKAdaForLoop(int HeaderBlockNum, int FollowBlockNum, FI CurrBlock->EmitSPARKAdaForFallThroughInsts(SPARKBodyFile); // all except last inst if it is control flow terminator for block vector<SMPInstr *>::reverse_iterator LastInstIter = CurrBlock->GetRevInstBegin(); SMPInstr *LastInst = (*LastInstIter); + STARS_ea_t LastAddr = LastInst->GetAddr(); + SMPitype FlowType = LastInst->GetDataFlowType(); if (LastInst->IsBasicBlockTerminator()) { - STARS_ea_t LastAddr = LastInst->GetAddr(); - SMPitype FlowType = LastInst->GetDataFlowType(); ControlFlowType LastCFType = this->GetControlFlowType(LastAddr); if (FlowType == INDIR_JUMP) { // Translate switch-case statement. - int NextFollowBlockNum = this->FindFollowBlockNum(CurrBlock); + int NextFollowBlockNum = this->FindFollowBlockNum(CurrBlock, true); this->EmitSPARKAdaForSwitch(CurrBlockNum, NextFollowBlockNum, SPARKBodyFile); ResumeBlockNum = NextFollowBlockNum; } @@ -9930,7 +9933,7 @@ void SMPFunction::EmitSPARKAdaForLoop(int HeaderBlockNum, int FollowBlockNum, FI } else if ((LastCFType == BRANCH_IF_THEN) || (LastCFType == BRANCH_IF_THEN_ELSE)) { // Translate if-else structure previously identified - int NextFollowBlockNum = this->FindFollowBlockNum(CurrBlock); + int NextFollowBlockNum = this->FindFollowBlockNum(CurrBlock, true); LastInst->EmitSPARKAda(SPARKBodyFile); // emit if (inverted condition) then this->EmitSPARKAdaForConditional(CurrBlockNum, NextFollowBlockNum, SPARKBodyFile); ResumeBlockNum = NextFollowBlockNum; @@ -9998,16 +10001,23 @@ void SMPFunction::EmitSPARKAdaForLoop(int HeaderBlockNum, int FollowBlockNum, FI else { // Last inst was translated by SMPBasicBlock::EmitSPARKAdaForFallThroughInsts(). // CurrBlock can only have one successor, a fall-through block. - assert(1 == CurrBlock->GetNumSuccessors()); - SMPBasicBlock *FallThroughSucc = (*(CurrBlock->GetFirstSucc())); - ResumeBlockNum = FallThroughSucc->GetNumber(); + // NOTE: If CurrBlock ends with a HALT or a call to a NORET function, we can have no successors. + size_t NumSuccessors = CurrBlock->GetNumSuccessors(); + if (1 == NumSuccessors) { + SMPBasicBlock *FallThroughSucc = (*(CurrBlock->GetFirstSucc())); + assert(NULL != FallThroughSucc); + ResumeBlockNum = FallThroughSucc->GetNumber(); + } + else { + assert(((FlowType == CALL) || (FlowType == HALT)) && (0 == NumSuccessors)); + } } // end if LastInst is basic block terminator ... else ... - - // We have translated the header block, and recursed into the next control flow structure if the end of the - // header block indicated a new structure was beginning. Time to pick up with ResumeBlock unless it is our - // follow block. - CurrBlockNum = ResumeBlockNum; } // end if loop tail block ... else ... + + // We have translated the header block, and recursed into the next control flow structure if the end of the + // header block indicated a new structure was beginning. Time to pick up with ResumeBlock unless it is our + // follow block. + CurrBlockNum = ResumeBlockNum; } // end while CurrBlockNum is in the loop return; @@ -10152,18 +10162,20 @@ void SMPFunction::EmitSPARKAdaForConditional(int HeaderBlockNum, int FollowBlock } // end of SMPFunction::EmitSPARKAdaForConditional() // Based on control flow structure of CurrBlock, find Ada follow block num; -1 if no structure besides fall-through -int SMPFunction::FindFollowBlockNum(SMPBasicBlock *CurrBlock) { +int SMPFunction::FindFollowBlockNum(SMPBasicBlock *CurrBlock, bool StartAtLastInst) { int FollowBlockNum = SMP_BLOCKNUM_UNINIT; - if (CurrBlock->IsLoopHeaderBlock()) { - int LoopNum = this->GetLoopNumFromHeaderBlockNum(CurrBlock->GetNumber()); - assert(0 <= LoopNum); - FollowBlockNum = this->LoopFollowNodes[LoopNum]; - assert(SMP_BLOCKNUM_UNINIT != FollowBlockNum); - } - else if (CurrBlock->IsSwitchDefaultCase()) { - STARS_ea_t DefaultCaseAddr = CurrBlock->GetFirstAddr(); - size_t SwitchIndex = this->FindSwitchIndexForDefaultCaseAddr(DefaultCaseAddr); - FollowBlockNum = this->SwitchInfoArray.at(SwitchIndex).FollowNodeNum; + if (!StartAtLastInst) { // StartAtLastInst => Key is to examine branch or jump, not starting a new loop or switch default case + if (CurrBlock->IsLoopHeaderBlock()) { + int LoopNum = this->GetLoopNumFromHeaderBlockNum(CurrBlock->GetNumber()); + assert(0 <= LoopNum); + FollowBlockNum = this->LoopFollowNodes[LoopNum]; + assert(SMP_BLOCKNUM_UNINIT != FollowBlockNum); + } + else if (CurrBlock->IsSwitchDefaultCase()) { + STARS_ea_t DefaultCaseAddr = CurrBlock->GetFirstAddr(); + size_t SwitchIndex = this->FindSwitchIndexForDefaultCaseAddr(DefaultCaseAddr); + FollowBlockNum = this->SwitchInfoArray.at(SwitchIndex).FollowNodeNum; + } } else { vector<SMPInstr *>::iterator LastInstIter = --(CurrBlock->GetLastInst()); @@ -10184,7 +10196,7 @@ int SMPFunction::FindFollowBlockNum(SMPBasicBlock *CurrBlock) { else if (FlowType == COND_BRANCH) { ControlFlowType LastCFType = GetControlFlowType(LastAddr); if (LastCFType == LOOP_EXIT) { - // Middle exit from loop. Follow block is fall-through. + // Middle exit from loop. Follow block is fall-through. !!!!****!!!! What structure has loop exit, then a follow block? list<SMPBasicBlock *>::iterator SuccIter = CurrBlock->GetFallThroughSucc(); assert(SuccIter != CurrBlock->GetLastSucc()); // COND_BRANCH must have fall through FollowBlockNum = (*SuccIter)->GetNumber(); diff --git a/src/base/SMPInstr.cpp b/src/base/SMPInstr.cpp index 0bd82941..ad7ced53 100644 --- a/src/base/SMPInstr.cpp +++ b/src/base/SMPInstr.cpp @@ -1685,7 +1685,7 @@ char *SMPInstr::GetDisasm(void) const { // Is the instruction the type that terminates a basic block? bool SMPInstr::IsBasicBlockTerminator() const { return ((type == JUMP) || (type == COND_BRANCH) - || (type == INDIR_JUMP) || (type == RETURN)); + || (type == INDIR_JUMP) || (type == RETURN) || (type == HALT)); } // Get non-flags DEF, usually for arithmetic opcode. @@ -2355,6 +2355,10 @@ void SMPInstr::MDEmitSPARKAdaCompareOrTest(FILE *OutFile) { this->PrintSPARKAdaOperand(RightOp, OutFile, false, UseFP); SMP_fprintf(OutFile, ");\n"); } + else { // TEST opcode always zeroes the CarryFlag + PrintSPARKIndentTabs(OutFile); + SMP_fprintf(OutFile, " X86.CarryFlag := 0;\n"); + } // OverflowFlag if (EmitOverflowFlag) { @@ -2372,6 +2376,10 @@ void SMPInstr::MDEmitSPARKAdaCompareOrTest(FILE *OutFile) { this->PrintSPARKAdaOperand(RightOp, OutFile, false, UseFP); SMP_fprintf(OutFile, " <= X86.MaxSignedInt%d)));\n", LeftBitWidth); } + else { // TEST opcode always zeroes the OverflowFlag + PrintSPARKIndentTabs(OutFile); + SMP_fprintf(OutFile, " X86.OverflowFlag := 0;\n"); + } return; } // end of SMPInstr::MDEmitSPARKAdaCompareOrTest() diff --git a/src/base/SMPProgram.cpp b/src/base/SMPProgram.cpp index 9205ba54..eda54ccb 100644 --- a/src/base/SMPProgram.cpp +++ b/src/base/SMPProgram.cpp @@ -843,7 +843,7 @@ bool SMPProgram::EmitProgramSPARKAda(void) { SMP_fprintf(BodyFile, "end %s;\n\n", LibFuncName.c_str()); } - // Loop through all functions and emit annotations for each. + // Loop through all functions and emit SPARK Ada for each. for (FuncIter = this->FuncMap.begin(); FuncIter != this->FuncMap.end(); ++FuncIter) { SMPFunction *TempFunc = FuncIter->second; if (TempFunc == NULL) continue; -- GitLab