From c25a6c28c8ae7e9ea4d739b5afeea3eff0b65ac5 Mon Sep 17 00:00:00 2001 From: Clark Coleman <clc@zephyr-software.com> Date: Thu, 27 Aug 2020 23:19:53 -0400 Subject: [PATCH] More fixes for SPARK translation crashes on large files. --- src/base/SMPBasicBlock.cpp | 15 +++++++++ src/base/SMPFunction.cpp | 63 +++++++++++++++++++++++++++++++------- src/base/SMPInstr.cpp | 5 ++- src/base/SMPProgram.cpp | 8 +++-- 4 files changed, 76 insertions(+), 15 deletions(-) diff --git a/src/base/SMPBasicBlock.cpp b/src/base/SMPBasicBlock.cpp index c10c6551..8854ed18 100644 --- a/src/base/SMPBasicBlock.cpp +++ b/src/base/SMPBasicBlock.cpp @@ -720,6 +720,14 @@ bool SMPBasicBlock::EmitSPARKAdaForExprUse(FILE *BodyFile, vector<SMPInstr *>::c Printed = false; return true; } + else if (CurrInst->MDIsConditionalMoveInstr()) { + // Need to handle expressions in the future that depend on guarded + // moves of operands, e.g. x86 "cmovge rax,rcx" + SMP_msg("ERROR: Not translating conditional move at %llx\n", (uint64_t)CurrAddr); + SMP_fprintf(BodyFile, "ERROR "); + Printed = false; + return true; + } else { SMPRegTransfer *DefRT = CurrInst->GetRT(0); assert(IsEqOp(DefRT->GetConstLeftOperandNoNorm(), UseOp)); @@ -786,6 +794,13 @@ bool SMPBasicBlock::EmitSPARKAdaForExprUse(FILE *BodyFile, vector<SMPInstr *>::c Printed = true; SMP_fprintf(BodyFile, ") "); } + else if (DefRightOp->IsVoidOp()) { + // Probably an odd unary operator, e.g. endianness byte-swap. + SMP_msg("ERROR: Not translating inst with no RightOp at %llx\n", (uint64_t)CurrAddr); + SMP_fprintf(BodyFile, "ERROR "); + Printed = false; + return true; + } else { STARSDefUseIter RightUseIter = CurrInst->FindUse(DefRightOp); assert(RightUseIter != CurrInst->GetLastUse()); diff --git a/src/base/SMPFunction.cpp b/src/base/SMPFunction.cpp index 05576858..50649601 100644 --- a/src/base/SMPFunction.cpp +++ b/src/base/SMPFunction.cpp @@ -11925,10 +11925,14 @@ int SMPFunction::TrackConditionalBranchTerminus(int BranchHeadBlockNum, int Curr #if 0 // Could do INVERTED_LOOP_EXIT by falling out of any block in the loop, not just the header block. assert(CurrBlock->IsLoopHeaderBlock()); #endif +#if 0 list<SMPBasicBlock *>::const_iterator SuccIter = CurrBlock->GetFallThroughSucc(); assert(SuccIter != CurrBlock->GetLastConstSucc()); int SuccBlockNum = (*SuccIter)->GetNumber(); WorkListBlockNums.push_back(SuccBlockNum); +#else + TerminusBlockNum = CurrBlockNum; // First good candidate, as conditional cannot span loop boundaries. +#endif } else { // add all successors to the work list for (list<SMPBasicBlock *>::const_iterator SuccIter = CurrBlock->GetFirstConstSucc(); SuccIter != CurrBlock->GetLastConstSucc(); ++SuccIter) { @@ -11977,8 +11981,9 @@ int SMPFunction::TrackConditionalBranchTerminus(int BranchHeadBlockNum, int Curr } BlocksSeen.SetBit((size_t) SuccBlockNum); - if (!this->DoesBlockDominateBlock(BranchHeadBlockNum, SuccBlockNum)) { - // We reached a block that is not dominated by BranchHeadBlockNum. + bool OutsideTheLoop = this->AreBlocksInSameLoops(BranchHeadBlockNum, SuccBlockNum); + if (OutsideTheLoop || (!this->DoesBlockDominateBlock(BranchHeadBlockNum, SuccBlockNum))) { + // We reached a block that is not dominated by BranchHeadBlockNum, or exited the loop. // Check for consistency with previous such blocks. if (0 <= TerminusBlockNum) { // had previous terminus if (SuccBlockNum != TerminusBlockNum) { @@ -13699,10 +13704,13 @@ bool SMPFunction::DoesBlockDominateBlock(int HeadBlockNum, int TailBlockNum) con // Recurse downward from HeadBlockNum in the dominator tree until we find TailBlockNum // or return false if we never find it. bool FoundIt = false; - for (list<int>::const_iterator ChildIter = this->DomTree.at(HeadBlockNum).second.begin(); + assert(((size_t)HeadBlockNum) < this->DomTree.size()); + assert(((size_t)TailBlockNum) < this->DomTree.size()); + for (list<int>::const_iterator ChildIter = this->DomTree.at(HeadBlockNum).second.begin(); ChildIter != this->DomTree.at(HeadBlockNum).second.end(); ++ChildIter) { int ChildBlockNum = (*ChildIter); + assert(((size_t)ChildBlockNum) < this->DomTree.size()); if (this->DoesBlockDominateBlock(ChildBlockNum, TailBlockNum)) { // recurse depth-first FoundIt = true; break; @@ -19268,7 +19276,9 @@ bool SMPFunction::EmitSPARKLoopMemRangePostCondition(FILE *HeaderFile, FILE *Bod size_t MemWidth = (*RelationalIter).first; STARSExprSetIter LowerExprIter = (*RelationalIter).second.first; STARSExprSetIter UpperExprIter = (*RelationalIter).second.second; - this->EmitSPARKMemRange(HeaderFile, false, true, HasArgs, (*LowerExprIter), (*UpperExprIter), OutputCount, MemWidth); + STARSExpression *LowerExpr = (*LowerExprIter); + STARSExpression *UpperExpr = (*UpperExprIter); + this->EmitSPARKMemRange(HeaderFile, false, true, HasArgs, LowerExpr, UpperExpr, OutputCount, MemWidth); } } // end if (HasRelationalExprs) @@ -19436,7 +19446,9 @@ void SMPFunction::EmitSPARKMemRangeLoopInvariants(FILE *BodyFile, size_t LoopInd size_t MemWidth = (*RelationalIter).first; STARSExprSetIter LowerExprIter = (*RelationalIter).second.first; STARSExprSetIter UpperExprIter = (*RelationalIter).second.second; - this->EmitSPARKMemRange(BodyFile, false, true, HasArgs, (*LowerExprIter), (*UpperExprIter), OutputCount, MemWidth); + STARSExpression *LowerExpr = (*LowerExprIter); + STARSExpression *UpperExpr = (*UpperExprIter); + this->EmitSPARKMemRange(BodyFile, false, true, HasArgs, LowerExpr, UpperExpr, OutputCount, MemWidth); } } @@ -20098,6 +20110,7 @@ void SMPFunction::EmitFuncSPARKAda(void) { if (this->IsLinkerStub()) { return; } + bool VerboseOutput = global_stars_interface->VerboseLoopsMode(); string AdaFuncName(this->GetFuncName()); #if STARS_EMIT_ADA_FOR_MAIN_ONLY @@ -20273,7 +20286,8 @@ void SMPFunction::EmitFuncSPARKAda(void) { } if (!TranslationComplete) { SMP_msg("ERROR: Incomplete SPARK Ada translation for %s\n", this->GetFuncName()); - this->Dump(); + if (VerboseOutput) + this->Dump(); } return; @@ -20778,6 +20792,11 @@ void SMPFunction::EmitSPARKProcPrePostMemConditions(FILE *BodyFile, FILE *Header #endif void SMPFunction::EmitSPARKMemRange(FILE *HeaderFile, bool PreconditionSection, bool ProcessingLoop, bool HasArgs, STARSExpression *LowerExpr, STARSExpression *UpperExpr, size_t &OutputCount, size_t MemWidth) { + if (nullptr == LowerExpr) { + SMP_msg("ERROR: SPARK: EmitSPARKMemRange() called with LowerExpr == nullptr in func at %llx\n", (uint64_t) this->GetFirstFuncAddr()); + return; + } + if (0 < OutputCount) { if (PreconditionSection) SMP_fprintf(HeaderFile, "\n\t\t or X86.InMemoryRange(i, "); @@ -20787,8 +20806,13 @@ void SMPFunction::EmitSPARKMemRange(FILE *HeaderFile, bool PreconditionSection, bool OldSuffix = (!(ProcessingLoop || PreconditionSection)); LowerExpr->EmitSPARKAda(HeaderFile, ProcessingLoop, OldSuffix, false, HasArgs, false, false); SMP_fprintf(HeaderFile, ", "); - UpperExpr->EmitSPARKAda(HeaderFile, ProcessingLoop, OldSuffix, false, HasArgs, false, false); - if (0 < MemWidth) { + if (nullptr != UpperExpr) { + UpperExpr->EmitSPARKAda(HeaderFile, ProcessingLoop, OldSuffix, false, HasArgs, false, false); + } + else { // Don't know upper bound. + SMP_fprintf(HeaderFile, "16#ffffffffffffffff"); + } + if ((0 < MemWidth) && (nullptr != UpperExpr)) { SMP_fprintf(HeaderFile, " + %zu) ", MemWidth); } else { @@ -21238,10 +21262,18 @@ string SMPFunction::EmitSPARKProcForLoopHeaderBlock(int LoopIndex, int HeaderBlo } VectorLimit = this->TempRangeExprWidthIters.size(); for (size_t VecIndex = 0; VecIndex < VectorLimit; ++VecIndex) { + // Print lower bound mem expr. STARSExpression *MemExpr = (*(this->TempRangeExprWidthIters[VecIndex].first)); MemExpr->PrintSPARKArgLocationStrings(HeaderFile, false, LoopNum, OutputCount, RegsPrinted); + // Print upper bound mem expr; if nullptr, print maximum limit. MemExpr = (*(this->TempRangeExprWidthIters[VecIndex].second)); - MemExpr->PrintSPARKArgLocationStrings(HeaderFile, false, LoopNum, OutputCount, RegsPrinted); + if (nullptr != MemExpr) { + MemExpr->PrintSPARKArgLocationStrings(HeaderFile, false, LoopNum, OutputCount, RegsPrinted); + } + else { // Don't know upper bound. + SMP_fprintf(HeaderFile, "16#ffffffffffffffff"); + ++OutputCount; + } } } // Print the incoming values of regs that got copied to address registers for mem writes. @@ -21267,7 +21299,12 @@ string SMPFunction::EmitSPARKProcForLoopHeaderBlock(int LoopIndex, int HeaderBlo for (size_t VecIndex = 0; VecIndex < VectorLimit; ++VecIndex) { STARSExpression *LowerExpr = (*this->TempRangeExprWidthIters[VecIndex].first); STARSExpression *UpperExpr = (*this->TempRangeExprWidthIters[VecIndex].second); - this->EmitSPARKMemRange(HeaderFile, true, true, HasArgs, LowerExpr, UpperExpr, OutputCount, 0); + if (nullptr == LowerExpr) { + SMP_msg("ERROR: SPARK: LowerExpr nullptr, VecIndex %zu in func at %llx\n", VecIndex, (uint64_t) this->GetFirstFuncAddr()); + } + else { + this->EmitSPARKMemRange(HeaderFile, true, true, HasArgs, LowerExpr, UpperExpr, OutputCount, 0); + } } } // end if (HasRangeExprs) @@ -21853,8 +21890,12 @@ void SMPFunction::EmitSPARKAdaForBlock(int CurrBlockNum, int FollowBlockNum, FIL else { // Nop at end of block could be for alignment, masking the control flow type of CALL // or HALT before it. - assert(((FlowType == CALL) || (FlowType == HALT) || CurrBlock->IsUnreachableBlock() || LastInst->IsNop()) + bool GoodCode = (((FlowType == CALL) || (FlowType == HALT) || CurrBlock->IsUnreachableBlock() || LastInst->IsNop()) && (0 == NumSuccessors)); + if (!GoodCode) { + SMP_msg("ERROR: SPARK: Bad control flow at end of block, inst at %llx\n", (uint64_t)LastInst->GetAddr()); + SMP_fprintf(SPARKBodyFile, "\nERROR\n"); + } } } } // end if header block ... elsif tail block ... else ... diff --git a/src/base/SMPInstr.cpp b/src/base/SMPInstr.cpp index 4e70da61..0e98b8d4 100644 --- a/src/base/SMPInstr.cpp +++ b/src/base/SMPInstr.cpp @@ -6115,6 +6115,7 @@ void SMPInstr::MDEmitSPARKAdaCompareOrTest(FILE *OutFile) { void SMPInstr::MDEmitSPARKAdaArithmeticSetsCondCodes(FILE *OutFile) { STARS_ea_t InstAddr = this->GetAddr(); SMPRegTransfer *CurrRT = this->RTL.GetRT(0); + bool VerboseOutput = global_stars_interface->VerboseLoopsMode(); assert((nullptr != CurrRT) && CurrRT->HasRightSubTree()); SMPoperator CurrOper = CurrRT->GetRightTree()->GetOperator(); bool ProcCallHandlesCondCodes = ((SMP_SUBTRACT_BORROW == CurrOper) || (SMP_ADD_CARRY == CurrOper)); @@ -6141,7 +6142,9 @@ void SMPInstr::MDEmitSPARKAdaArithmeticSetsCondCodes(FILE *OutFile) { set<int> LiveFlagRegs; bool LiveFlags = this->GetBlock()->AreFlagsLiveAfterInst(InstAddr, LiveFlagRegs); if (!LiveFlags) { - SMP_msg("INFO: Arithmetic inst at %llx with no live flags used after inst.\n", (uint64_t) InstAddr); + if (VerboseOutput) { + SMP_msg("INFO: Arithmetic inst at %llx with no live flags used after inst.\n", (uint64_t)InstAddr); + } // Reset default flags to false. EmitCarryFlag = false; EmitZeroFlag = false; diff --git a/src/base/SMPProgram.cpp b/src/base/SMPProgram.cpp index 52976f64..ec6ed4fb 100644 --- a/src/base/SMPProgram.cpp +++ b/src/base/SMPProgram.cpp @@ -1158,9 +1158,11 @@ bool SMPProgram::EmitProgramSPARKAda(void) { SMP_fprintf(BodyFile, "end %s;\n\n", TempFunc->GetFuncName()); // if (0 == strcmp("main", TempFunc->GetFuncName())) - bool EdgeSuccess = TempFunc->ComputeEdgeExpressions(); - if (global_stars_interface->VerboseLoopsMode()) { - TempFunc->Dump(); + if (TempFunc->HasGoodSSAForm()) { + bool EdgeSuccess = TempFunc->ComputeEdgeExpressions(); + if (global_stars_interface->VerboseLoopsMode()) { + TempFunc->Dump(); + } } } } -- GitLab