From 2feb303ac8c8a18c5ba16602ecdc00457299c7d5 Mon Sep 17 00:00:00 2001
From: Clark Coleman <clc@zephyr-software.com>
Date: Fri, 2 Oct 2020 00:26:08 -0400
Subject: [PATCH] SPARK fix; debugging enhancements.

---
 src/base/SMPFunction.cpp | 16 +++++++++++++---
 src/base/SMPInstr.cpp    | 11 ++++++++---
 2 files changed, 21 insertions(+), 6 deletions(-)

diff --git a/src/base/SMPFunction.cpp b/src/base/SMPFunction.cpp
index a2982101..d9972655 100644
--- a/src/base/SMPFunction.cpp
+++ b/src/base/SMPFunction.cpp
@@ -11731,6 +11731,7 @@ bool SMPFunction::AnalyzeConditionalStatements(void) {
 // Find candidate block # for if-else follow node for HeadBlockNum; return -1 otherwise
 int SMPFunction::FindConditionalFollowNode(int HeadBlockNum) {
 	int FollowBlockNum = SMP_BLOCKNUM_UNINIT;
+	bool VerboseOutput = global_stars_interface->VerboseSPARKMode();
 
 	// Guard against pathological code like jz $+2 which jumps and falls through
 	//  to the same ensuing instruction.
@@ -11807,6 +11808,7 @@ int SMPFunction::FindConditionalFollowNode(int HeadBlockNum) {
 						SMP_msg("ERROR: SPARK: Unstructured due to Loop-spanning branch to block %d from block %zu in func %s\n", SuccBlockNum, BlockIndex, this->GetFuncName());
 						FollowBlockNum = SMP_BLOCKNUM_UNINIT; // error signal
 						this->DumpDotCFG();
+						if (VerboseOutput)
 						this->Dump();
 						return FollowBlockNum;
 					}
@@ -12297,7 +12299,10 @@ void SMPFunction::FindGuardedLoops(void) {
 			assert(STARS_BADADDR != LastInstAddr);
 			ControlFlowType LastCFType = this->GetControlFlowType(LastInstAddr);
 			if (LastCFType == BRANCH_IF_THEN) {
-				list<SMPBasicBlock *>::const_iterator FallThroughBlockIter = CurrBlock->GetFallThroughSucc();
+				SMPInstr *BranchInst = this->GetInstFromAddr(LastInstAddr);
+				bool OddIfThenCase = BranchInst->IsOddIfThenCase(); // jumps to THEN case instead of falling through to it
+				list<SMPBasicBlock *>::const_iterator FallThroughBlockIter = OddIfThenCase ? CurrBlock->GetCondNonFallThroughSucc() : CurrBlock->GetFallThroughSucc();
+				assert(FallThroughBlockIter != CurrBlock->GetLastConstSucc());
 				bool FoundGuardedLoop = false;
 				STARS_ea_t LoopAddr = STARS_BADADDR;
 				SMPBasicBlock *FallThroughBlock = (*FallThroughBlockIter);
@@ -16576,6 +16581,7 @@ void SMPFunction::UpdateLoopFollowBlockNum(int LoopHeadBlockNum, int FollowBlock
 	assert(SMP_BLOCKNUM_UNINIT != LoopHeadBlockNum);
 	size_t LoopNum = this->FindLoopNumFromHeadBlockNum(LoopHeadBlockNum);
 	int OldFollowNum = this->LoopFollowNodes[LoopNum];
+	bool VerboseOutput = global_stars_interface->VerboseSPARKMode();
 
 	// Safeguard against infinite loops. If our follow node is inside our loop,
 	//  we want to leave SMP_BLOCKNUM_UNINIT as the follow node. Ditto, if the follow node
@@ -16629,6 +16635,9 @@ void SMPFunction::UpdateLoopFollowBlockNum(int LoopHeadBlockNum, int FollowBlock
 					this->HasGoodLoopFollowBlocks = false;
 					SMP_msg("ERROR: SPARK: Unstructured due to conflicting loop follow block nums for loop %d : %d and %d in %s\n",
 						LoopNum, OldFollowNum, FollowBlockNum, this->GetFuncName());
+					if (VerboseOutput)
+						this->Dump();
+					this->DumpDotCFG();
 				}
 			}
 		}
@@ -20691,7 +20700,7 @@ void SMPFunction::EmitFuncSPARKAda(void) {
 	if (this->IsLinkerStub()) {
 		return;
 	}
-	bool VerboseOutput = global_stars_interface->VerboseLoopsMode();
+	bool VerboseOutput = global_stars_interface->VerboseSPARKMode();
 
 	string AdaFuncName(this->GetFuncName());
 #if STARS_EMIT_ADA_FOR_MAIN_ONLY
@@ -20861,7 +20870,8 @@ void SMPFunction::EmitFuncSPARKAda(void) {
 			STARS_ea_t InstAddr = CurrInst->GetAddr();
 			SMPBasicBlock *CurrBlock = this->GetBlockFromInstAddr(InstAddr);
 			assert(nullptr != CurrBlock);
-			SMP_fprintf(BodyFile, "ERROR: Instruction at %llx not translated.\n", (uint64_t)InstAddr);
+			SMP_fprintf(BodyFile, "ERROR: Instruction at %llx block %d not translated.\n",
+				(uint64_t)InstAddr, CurrBlock->GetNumber());
 			TranslationComplete = false;
 		}
 	}
diff --git a/src/base/SMPInstr.cpp b/src/base/SMPInstr.cpp
index 180e1692..98b9e188 100644
--- a/src/base/SMPInstr.cpp
+++ b/src/base/SMPInstr.cpp
@@ -6142,7 +6142,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();
+	bool VerboseOutput = global_stars_interface->VerboseSPARKMode();
 	assert((nullptr != CurrRT) && CurrRT->HasRightSubTree());
 	SMPoperator CurrOper = CurrRT->GetRightTree()->GetOperator();
 	bool ProcCallHandlesCondCodes = ((SMP_SUBTRACT_BORROW == CurrOper) || (SMP_ADD_CARRY == CurrOper)); 
@@ -9074,10 +9074,15 @@ bool SMPInstr::IsBranchToFarChunk(void) {
 
 // instr branches or jumps to another function
 bool SMPInstr::IsBranchToOtherFunc(void) {
+	bool TargetInOtherFunc = false;
 	bool Safe = (nullptr != this->GetBlock());
 	STARS_ea_t FarTarget = this->GetJumpTarget();
-	return (Safe && (STARS_BADADDR != FarTarget) && (!this->GetBlock()->GetFunc()->IsInstIDInFunc(FarTarget)));
-}
+	bool Sane = (Safe && (STARS_BADADDR != FarTarget));
+	if (Sane) {
+		TargetInOtherFunc = (!this->GetBlock()->GetFunc()->IsInstIDInFunc(FarTarget));
+	}
+	return TargetInOtherFunc;
+} // end of SMPInstr::IsBranchToOtherFunc()
 
 // is poorly-optimized if-then COND_BRANCH with extra jumps
 bool SMPInstr::IsOddIfThenCase(void) const {
-- 
GitLab