if (this->TCFGBlocks.size() > this->TCFGDomSoFar.GetNumBits()) {
SMP_msg("ERROR: SPARK: Unstructured due to TCFG size bloat after cloning ");
this->DumpFuncNameAndAddr();
this->PrintedSPARKUnstructuredMsg = true;
this->DumpDotCFG();
StructuredConditional = false;
}
return StructuredConditional;
} // end of SMPFunction::AnalyzeConditionalStatements()
...
...
@@ -13685,13 +13716,25 @@ int SMPFunction::FindConditionalFollowNode4(const int HeadBlockNum, bool &IfThen
// Side entrances into both FTBlock and NFTBlock. Cloning can structure it.
// The FTBlock and NFTBlock already have convergence at their DomFrontiers, just have dominance problem.
// We can relax the NoDeadEnds requirement and clone through dead ends later.
SMP_msg("INFO: SPARK: Cloning doubly from %d and %d to %d would solve DomFrontier non-convergence for HeadBlock %d NoDeadEnds %d ", FTBlockNum, NFTBlockNum, FollowBlockNum, HeadBlockNum, NoDeadEnds);
@@ -13868,9 +13907,9 @@ bool SMPFunction::IsCloningSafe(const int StartTCFGBlockNum, const int LimitTCFG
// Push cloned blocks onto end of TCFGBlocks.
// Update ClonedShadowCFGBlocks in lockstep with TCFGBlocks.
void SMPFunction::MarkBlocksAndClone(const int StartingBlockNum, const int UnlinkBlockNum, const int LimitBlockNum, const int InnermostLoopNum, bool FirstIter) {
size_t FirstClonedBlockIndex = 0;
if (FirstIter) {
this->CloningMap.clear();
this->CloningReverseMap.clear();
FirstClonedBlockIndex = this->TCFGBlocks.size();
}
bool InsideLoop = (0 <= InnermostLoopNum);
...
...
@@ -13964,8 +14003,9 @@ void SMPFunction::MarkBlocksAndClone(const int StartingBlockNum, const int Unlin
}
}
}
else if (!this->CloningMap.empty()) {
// We are finished cloning on this subpath. Update the JumpFollowNodesMap.
if (!this->CloningMap.empty() && FirstIter) {
// We are finished cloning on this path. Update the JumpFollowNodesMap.
// Update JumpFollowNodesMap. For a current pair <jumpblocknum, targetblocknum> we have four possibilities:
// 1. Neither block was cloned; do nothing
// 2. Only targetblock was cloned; if jumpblocknum==unlinkblocknum, handled in FirstIter code above, else cannot be structured.
...
...
@@ -14018,6 +14058,46 @@ void SMPFunction::MarkBlocksAndClone(const int StartingBlockNum, const int Unlin
} // end for all CloneMapItems
CloneMapItems.clear();
}
// Update block numbers only in the short-circuit blocks that were just cloned.
// This step is needed now because of the double-cloning possibility. If we have
// two items in the SPARKCloningWorkList, we need to keep track of block numbers
// at each step, not just after renumbering all blocks in UpdateAfterCloning().
for (size_t ClonedBlockIndex = FirstClonedBlockIndex; ClonedBlockIndex < this->TCFGBlocks.size(); ++ClonedBlockIndex) {