From deaa0caa8fc19503caafb3dfb05d89b87b594089 Mon Sep 17 00:00:00 2001
From: Clark Coleman <clc@zephyr-software.com>
Date: Fri, 2 Oct 2020 14:17:58 -0400
Subject: [PATCH] SPARK: Use StaysInLoop logic for tail block fall-throughs in
 one more place; reduce loop expr log file output.

---
 src/base/SMPFunction.cpp | 26 ++++++++++++++++++++------
 src/base/SMPInstr.cpp    | 24 ++++++++++++++++--------
 2 files changed, 36 insertions(+), 14 deletions(-)

diff --git a/src/base/SMPFunction.cpp b/src/base/SMPFunction.cpp
index d9972655..23050c91 100644
--- a/src/base/SMPFunction.cpp
+++ b/src/base/SMPFunction.cpp
@@ -22309,15 +22309,18 @@ void SMPFunction::EmitSPARKAdaForBlock(int CurrBlockNum, int FollowBlockNum, FIL
 		}
 		else if (CurrBlock->IsLoopTailBlock()) {
 			// assert(false);
-			// We are at the end of a recursive descent into a loop. Translate the block and return to EmitSPARKAdaForLoop().
+			ControlFlowType LastCFType = CurrBlock->GetLastInstCFType();
+			vector<SMPInstr *>::const_reverse_iterator LastInstIter = CurrBlock->GetRevInstCBegin();
+			SMPInstr *LastInst = (*LastInstIter);
+			SMPitype FlowType = LastInst->GetDataFlowType();
+			STARS_ea_t LastInstAddr = LastInst->GetAddr();
+			// We are at the end of a recursive descent into a loop. Translate the block and return to 
+			//  EmitSPARKAdaForLoop() unless we are starting a conditional inside the loop when the LOOP_BACK
+			//  branch is not taken.
 			if (CurrBlock->HasLoopHeadWithInvertedExitAsSuccessor()) {
 				// Last inst in block is transfer to loop head. Need to ensure that we don't
 				//  emit "end loop;" before we return to our caller and emit "end if;" in order
 				//  to get proper nesting of control structures. 
-				ControlFlowType LastCFType = CurrBlock->GetLastInstCFType();
-				vector<SMPInstr *>::const_reverse_iterator LastInstIter = CurrBlock->GetRevInstCBegin();
-				SMPInstr *LastInst = (*LastInstIter);
-				SMPitype FlowType = LastInst->GetDataFlowType();
 				if (JUMP == FlowType) {
 					// One branch of an if-then-else can fall through to the inverted-exit loop head.
 					//  The other branch jumps to the loop header.
@@ -22357,7 +22360,18 @@ void SMPFunction::EmitSPARKAdaForBlock(int CurrBlockNum, int FollowBlockNum, FIL
 				}
 			}
 			else {
-				CurrBlock->EmitSPARKAdaForAllInsts(SPARKBodyFile);
+				bool StaysInLoop = this->IsNonExitingLoopBackBranch(LastInstAddr);
+				if (!StaysInLoop) { // just loop-back and return to EmitSPARKAdaForLoop().
+					CurrBlock->EmitSPARKAdaForAllInsts(SPARKBodyFile);
+				}
+				else {
+					// We need to emit the fall through insts, then translate COND_BRANCH to loop header
+					//  into if (inverted condition) then ... for the rest of the loop body.
+					CurrBlock->EmitSPARKAdaForFallThroughInsts(SPARKBodyFile);
+					// EmitSPARKAdaForConditional() will emit the if (inverted condition) then ... and
+					//  will continue through the rest of the if-then body.
+					this->EmitSPARKAdaForConditional(CurrBlockNum, FollowBlockNum, SPARKBodyFile);
+				}
 			}
 			return;
 		}
diff --git a/src/base/SMPInstr.cpp b/src/base/SMPInstr.cpp
index 98b9e188..90b69a51 100644
--- a/src/base/SMPInstr.cpp
+++ b/src/base/SMPInstr.cpp
@@ -4280,6 +4280,7 @@ bool STARSExpression::ExpandOperandHelper(STARS_ea_t DefAddr, const STARSOpndTyp
 	set<int> &LoopRegHashes, bool &StoppedOnIV, bool &changed, set<STARS_ea_t> &StackPtrCopySet, int &DepthCounter) {
 	bool success = true;
 	bool UseFP = this->GetParentFunc()->UsesFramePointer();
+	bool VerboseOutput = global_stars_interface->VerboseLoopsMode();
 	// See if we have crossed the beginning-of-loop boundary for the first time.
 	STARS_ea_t CurrLoopDefAddr = Left ? this->GetLeftPreLoopDefAddr() : this->GetRightPreLoopDefAddr();
 	STARSInductionVarFamilyList::iterator IVFamilyIter;
@@ -4317,10 +4318,12 @@ bool STARSExpression::ExpandOperandHelper(STARS_ea_t DefAddr, const STARSOpndTyp
 		success = (StopOnIV && this->GetParentFunc()->IsLoopNestInductionVar(SearchOp, this->GetParentInst(), IVFamilyIter, FamilyIndex, LoopIndex));
 		if (success) {
 			StoppedOnIV = true;
-			SMP_msg("INFO: StoppedOnIV at DefAddr %llx for ParentInst at %llx\n", (uint64_t) DefAddr, (uint64_t) this->GetParentInst()->GetAddr());
-			SMP_msg("INFO: StoppedOnIV SearchOp was: ");
-			PrintOperand(SearchOp);
-			SMP_msg("\n");
+			if (VerboseOutput) {
+				SMP_msg("INFO: StoppedOnIV at DefAddr %llx for ParentInst at %llx\n", (uint64_t)DefAddr, (uint64_t) this->GetParentInst()->GetAddr());
+				SMP_msg("INFO: StoppedOnIV SearchOp was: ");
+				PrintOperand(SearchOp);
+				SMP_msg("\n");
+			}
 		}
 		if (success && (STARS_BADADDR == CurrLoopDefAddr)) {
 #if 0
@@ -4773,6 +4776,7 @@ STARSOpndTypePtr STARSExpression::FindLeftPreLoopDefOp(void) const {
 bool STARSExpression::AreAllRegsLoopInvariant(void) const {
 	bool LoopInvariantExpr = true;
 	bool UseFP = this->GetParentFunc()->UsesFramePointer();
+	bool VerboseOutput = global_stars_interface->VerboseLoopsMode();
 
 	if (this->HasLeftSubTree()) {
 		LoopInvariantExpr = this->GetLeftTree()->AreAllRegsLoopInvariant();
@@ -4787,8 +4791,10 @@ bool STARSExpression::AreAllRegsLoopInvariant(void) const {
 			int SSANum = this->GetLeftSSANum();
 			STARS_ea_t DefAddr = CurrBlock->GetDefAddrFromUseAddr(CurrOp, UseAddr, SSANum, LocalName);
 			if (STARS_IsBlockNumPseudoID(DefAddr)) {
-				SMP_msg("INFO: Phi DEF termination in STARSExpression::AreAllRegsLoopInvariant() at UseAddr %llx DefAddr %llx\n",
-					(uint64_t)UseAddr, (uint64_t)DefAddr);
+				if (VerboseOutput) {
+					SMP_msg("INFO: Phi DEF termination in STARSExpression::AreAllRegsLoopInvariant() at UseAddr %llx DefAddr %llx\n",
+						(uint64_t)UseAddr, (uint64_t)DefAddr);
+				}
 				LoopInvariantExpr = false;
 			}
 			else if (STARS_BADADDR == DefAddr) {
@@ -4834,8 +4840,10 @@ bool STARSExpression::AreAllRegsLoopInvariant(void) const {
 				int SSANum = this->GetRightSSANum();
 				STARS_ea_t DefAddr = CurrBlock->GetDefAddrFromUseAddr(CurrOp, UseAddr, SSANum, LocalName);
 				if (STARS_IsBlockNumPseudoID(DefAddr)) {
-					SMP_msg("INFO: Phi DEF termination in STARSExpression::AreAllRegsLoopInvariant() at UseAddr %llx DefAddr %llx\n",
-						(uint64_t)UseAddr, (uint64_t)DefAddr);
+					if (VerboseOutput) {
+						SMP_msg("INFO: Phi DEF termination in STARSExpression::AreAllRegsLoopInvariant() at UseAddr %llx DefAddr %llx\n",
+							(uint64_t)UseAddr, (uint64_t)DefAddr);
+					}
 					LoopInvariantExpr = false;
 				}
 				else {
-- 
GitLab