diff --git a/src/base/SMPDataFlowAnalysis.cpp b/src/base/SMPDataFlowAnalysis.cpp index 9d294807a99407f6086a35f3fa5b1048486743e0..694d8cc226fe8b95f213a863e70326ab06248a5c 100644 --- a/src/base/SMPDataFlowAnalysis.cpp +++ b/src/base/SMPDataFlowAnalysis.cpp @@ -428,6 +428,12 @@ bool IsEqOpIgnoreBitwidth(const STARSOpndTypePtr &Opnd1, const STARSOpndTypePtr // Are operands equal, ignoring value differences for immediate operands? bool IsEqOpIgnoreImmedValues(const STARSOpndTypePtr &Opnd1, const STARSOpndTypePtr &Opnd2) { + if (nullptr == Opnd1) + return (nullptr == Opnd2); + + if (nullptr == Opnd2) + return (nullptr == Opnd1); + if (Opnd1->GetOpType() != Opnd2->GetOpType()) return false; diff --git a/src/base/SMPFunction.cpp b/src/base/SMPFunction.cpp index 8642e027727d220bdf09109ca0b5ce34a404f817..22f555c3414da4a2da821adef45a56dd5572356a 100644 --- a/src/base/SMPFunction.cpp +++ b/src/base/SMPFunction.cpp @@ -743,6 +743,9 @@ bool SMPFunction::InheritCalleeMemRangeExpr(STARSExpression *CalleeMemRangeExpr, SMP_msg("ERROR: SPARK: Callee loop range expr too deep to trace to InArg at call site %llx\n", (uint64_t) InstAddr); CalleeMemRangeExpr->Dump(0); } + if (!FoundInArg) + return Changed; + bool GlobalStaticMemOp = InArgOp->IsStaticMemOp() || (InArgOp->IsImmedOp() && IsImmedGlobalAddress((STARS_ea_t) InArgOp->GetImmedValue())); if (GlobalStaticMemOp) { // We need to find an InArg, if any, as an index reg on the right hand side. @@ -1356,9 +1359,9 @@ void SMPFunction::SetControlFlowType(STARS_ea_t InstAddr, ControlFlowType JumpTy if (ExitCase) { MapIter->second = (unsigned short) JumpTypeCode; } - else { + else if (MapIter->second != ((unsigned short) JumpTypeCode)) { SMP_msg("WARNING: SPARK Ada jump type changing from %u to %u at %llx: rejected\n", MapIter->second, - (unsigned short)JumpTypeCode, (unsigned long long) InstAddr); + (unsigned short) JumpTypeCode, (unsigned long long) InstAddr); #if 0 // refuse to override past value MapIter->second = (unsigned short) JumpTypeCode; #endif @@ -8857,11 +8860,18 @@ bool SMPFunction::AnalyzeCompoundConditionalStatements(void) { STARS_ea_t LastAddr = OrigBlock->GetLastAddr(); ControlFlowType LastCFType = this->GetControlFlowType(LastAddr); if (SHORT_CIRCUIT_BRANCH == LastCFType) { // not SHORT_CIRCUIT_LOOP_EXIT - int FollowBlockNum = this->FindConditionalFollowNode((int)BlockIndex); + int FollowBlockNum = this->FindConditionalFollowNode((int) BlockIndex); if (SMP_BLOCKNUM_UNINIT == FollowBlockNum) { + SMP_msg("ERROR: Cannot find follow block for SHORT_CIRCUIT_BRANCH in block %zu in %s\n", + BlockIndex, this->GetFuncName()); Structured = false; break; } + else if (SMP_BLOCKNUM_COMMON_RETURN == FollowBlockNum) { + SMP_msg("INFO: Common return follow block for SHORT_CIRCUIT_BRANCH in block %zu in %s\n", + BlockIndex, this->GetFuncName()); + continue; // no code re-arranging to do + } STARSCondExpr *CurrExpr = CurrCFGBlock->GetExpr(); int FTBlockNum = CurrExpr->GetFallThroughBlockNum(); int NFTBlockNum = CurrExpr->GetNonFallThroughBlockNum(); @@ -8898,6 +8908,8 @@ bool SMPFunction::AnalyzeCompoundConditionalStatements(void) { } else { Structured = false; + SMP_msg("ERROR: In inverted SHORT_CIRCUIT_BRANCH at block %zu FTBlockNum: %d not > than NFTBlockNum: %d in %s\n", + BlockIndex, FTBlockNum, NFTBlockNum, this->GetFuncName()); break; } } @@ -8938,9 +8950,18 @@ bool SMPFunction::AnalyzeCompoundConditionalStatements(void) { pair<STARS_ea_t, int> MapItem(LastAddr, FollowBlockNum); pair<map<STARS_ea_t, int>::iterator, bool> InsertResult = this->JumpFollowNodesMap.insert(MapItem); if (!InsertResult.second) { - SMP_msg("ERROR: SPARK CFG JumpFollowNodesMap conflict at %llx\n", (uint64_t)LastAddr); - Structured = false; - break; + // Were we inserting the same follow node again, or a conflicting follow node? + map<STARS_ea_t, int>::iterator ExistingValueIter = InsertResult.first; + int OldFollowBlockNum = ExistingValueIter->second; + if (OldFollowBlockNum != FollowBlockNum) { + SMP_msg("ERROR: SPARK CFG JumpFollowNodesMap conflict at %llx Old: %d New:%d\n", + (uint64_t) LastAddr, OldFollowBlockNum, FollowBlockNum); + Structured = false; + break; + } + else { + SMP_msg("INFO: SPARK CFG JumpFollowNodesMap redundant update at %llx\n", (uint64_t) LastAddr); + } } } } @@ -8951,9 +8972,18 @@ bool SMPFunction::AnalyzeCompoundConditionalStatements(void) { pair<STARS_ea_t, int> MapItem(LastAddr, FollowBlockNum); pair<map<STARS_ea_t, int>::iterator, bool> InsertResult = this->JumpFollowNodesMap.insert(MapItem); if (!InsertResult.second) { - SMP_msg("ERROR: SPARK CFG JumpFollowNodesMap conflict at %llx\n", (uint64_t)LastAddr); - Structured = false; - break; + // Were we inserting the same follow node again, or a conflicting follow node? + map<STARS_ea_t, int>::iterator ExistingValueIter = InsertResult.first; + int OldFollowBlockNum = ExistingValueIter->second; + if (OldFollowBlockNum != FollowBlockNum) { + SMP_msg("ERROR: SPARK CFG JumpFollowNodesMap conflict at %llx Old: %d New:%d\n", + (uint64_t)LastAddr, OldFollowBlockNum, FollowBlockNum); + Structured = false; + break; + } + else { + SMP_msg("INFO: SPARK CFG JumpFollowNodesMap redundant update at %llx\n", (uint64_t)LastAddr); + } } } } // end if SHORT_CIRCUIT_BRANCH i.e. not SHORT_CIRCUIT_LOOP_EXIT @@ -9010,9 +9040,18 @@ bool SMPFunction::AnalyzeConditionalStatements(void) { pair<STARS_ea_t, int> MapItem(LastAddr, FollowNodeNum); pair<map<STARS_ea_t, int>::iterator, bool> InsertResult = this->JumpFollowNodesMap.insert(MapItem); if (!InsertResult.second) { - SMP_msg("ERROR: SPARK CFG JumpFollowNodesMap conflict at %llx\n", (uint64_t) LastAddr); - StructuredConditional = false; - break; + // Were we inserting the same follow node again, or a conflicting follow node? + map<STARS_ea_t, int>::iterator ExistingValueIter = InsertResult.first; + int OldFollowBlockNum = ExistingValueIter->second; + if (OldFollowBlockNum != FollowNodeNum) { + SMP_msg("ERROR: SPARK CFG JumpFollowNodesMap conflict at %llx Old: %d New:%d\n", + (uint64_t) LastAddr, OldFollowBlockNum, FollowNodeNum); + StructuredConditional = false; + break; + } + else { + SMP_msg("INFO: SPARK CFG JumpFollowNodesMap redundant update at %llx\n", (uint64_t) LastAddr); + } } this->SetControlFlowType(LastAddr, BRANCH_IF_THEN_ELSE); @@ -9027,13 +9066,22 @@ bool SMPFunction::AnalyzeConditionalStatements(void) { pair<STARS_ea_t, int> MapItem(ElsifAddr, FollowNodeNum); pair<map<STARS_ea_t, int>::iterator, bool> InsertResult = this->JumpFollowNodesMap.insert(MapItem); if (!InsertResult.second) { - SMP_msg("ERROR: SPARK CFG JumpFollowNodesMap conflict at %llx\n", (uint64_t) ElsifAddr); - StructuredConditional = false; - break; + // Were we inserting the same follow node again, or a conflicting follow node? + map<STARS_ea_t, int>::iterator ExistingValueIter = InsertResult.first; + int OldFollowBlockNum = ExistingValueIter->second; + if (OldFollowBlockNum != FollowNodeNum) { + SMP_msg("ERROR: SPARK CFG JumpFollowNodesMap conflict at %llx Old: %d New:%d\n", + (uint64_t) ElsifAddr, OldFollowBlockNum, FollowNodeNum); + StructuredConditional = false; + break; + } + else { + SMP_msg("INFO: SPARK CFG JumpFollowNodesMap redundant update at %llx\n", (uint64_t) ElsifAddr); + } } } // end for each UnresolvedBranchBlock if (!UnresolvedBranchBlocks.empty()) { - SMP_msg("INFO: SPARK CFG Resolved to ELSIF at %llx\n", (uint64_t)LastAddr); + SMP_msg("INFO: SPARK CFG Resolved to ELSIF at %llx\n", (uint64_t) LastAddr); } UnresolvedBranchBlocks.clear(); } @@ -9082,9 +9130,18 @@ bool SMPFunction::AnalyzeConditionalStatements(void) { pair<STARS_ea_t, int> MapItem(ElsifAddr, FollowNodeNum); pair<map<STARS_ea_t, int>::iterator, bool> InsertResult = this->JumpFollowNodesMap.insert(MapItem); if (!InsertResult.second) { - SMP_msg("ERROR: SPARK CFG JumpFollowNodesMap conflict at %llx\n", (uint64_t) ElsifAddr); - StructuredConditional = false; - break; + // Were we inserting the same follow node again, or a conflicting follow node? + map<STARS_ea_t, int>::iterator ExistingValueIter = InsertResult.first; + int OldFollowBlockNum = ExistingValueIter->second; + if (OldFollowBlockNum != FollowNodeNum) { + SMP_msg("ERROR: SPARK CFG JumpFollowNodesMap conflict at %llx Old: %d New:%d\n", + (uint64_t) ElsifAddr, OldFollowBlockNum, FollowNodeNum); + StructuredConditional = false; + break; + } + else { + SMP_msg("INFO: SPARK CFG JumpFollowNodesMap redundant update at %llx\n", (uint64_t) ElsifAddr); + } } // Find out if the unresolved branch should be translated as beginning a nested if-then, or a nested // if-then-else. The key is whether the COND_BRANCH goes to the follow node directly (if-then) or @@ -9103,9 +9160,18 @@ bool SMPFunction::AnalyzeConditionalStatements(void) { pair<STARS_ea_t, int> MapItem(LastAddr, FollowNodeNum); pair<map<STARS_ea_t, int>::iterator, bool> InsertResult = this->JumpFollowNodesMap.insert(MapItem); if (!InsertResult.second) { - SMP_msg("ERROR: SPARK CFG JumpFollowNodesMap conflict at %llx\n", (uint64_t) LastAddr); - StructuredConditional = false; - break; + // Were we inserting the same follow node again, or a conflicting follow node? + map<STARS_ea_t, int>::iterator ExistingValueIter = InsertResult.first; + int OldFollowBlockNum = ExistingValueIter->second; + if (OldFollowBlockNum != FollowNodeNum) { + SMP_msg("ERROR: SPARK CFG JumpFollowNodesMap conflict at %llx Old: %d New:%d\n", + (uint64_t) LastAddr, OldFollowBlockNum, FollowNodeNum); + StructuredConditional = false; + break; + } + else { + SMP_msg("INFO: SPARK CFG JumpFollowNodesMap redundant update at %llx\n", (uint64_t) LastAddr); + } } } // end if (bad follownode) ... else ... } // end if COND_BRANCH @@ -9120,21 +9186,32 @@ int SMPFunction::FindConditionalFollowNode(int HeadBlockNum) { int FollowBlockNum = SMP_BLOCKNUM_UNINIT; // A well-structured candidate would be the biggest RPO-number block that has >= 2 predecessors - // and has HeadBlockNum as its IDom. EXCEPTION: Return instructions interrupt control flow. See below. - - // Go through IDoms in reverse order until we find a well-structured candidate or hit HeadBlockNum. - int IDomIndex = (int) this->IDom.size() - 1; - while (IDomIndex > HeadBlockNum) { - if (this->IDom[IDomIndex] == HeadBlockNum) { - // COND_BRANCH block is the IDom for block # IDomIndex. - if (2 <= this->RPOBlocks[IDomIndex]->GetNumPredsMinusBackEdges()) { // success - FollowBlockNum = IDomIndex; - break; + // and has HeadBlockNum as its IDom. + // EXCEPTION #1: Return instructions interrupt control flow. See below. + // EXCEPTION #2: Short circuit conditionals can trick the IDom algorithm into choosing + // one of the blocks in the short circuit expression as the follow node, when the follow + // node should come after the entire short circuit expr. + + SMPBasicBlock *HeadBlock = this->RPOBlocks[HeadBlockNum]; + assert(nullptr != HeadBlock); + STARS_ea_t HeadLastAddr = HeadBlock->GetLastAddr(); + ControlFlowType LastCFType = this->GetControlFlowType(HeadLastAddr); + bool ShortCircuit = ((LastCFType == SHORT_CIRCUIT_BRANCH) || (LastCFType == SHORT_CIRCUIT_LOOP_EXIT)); + + if (!ShortCircuit) { + // Go through IDoms in reverse order until we find a well-structured candidate or hit HeadBlockNum. + int IDomIndex = (int) this->IDom.size() - 1; + while (IDomIndex > HeadBlockNum) { + if (this->IDom[IDomIndex] == HeadBlockNum) { + // COND_BRANCH block is the IDom for block # IDomIndex. + if (2 <= this->RPOBlocks[IDomIndex]->GetNumPredsMinusBackEdges()) { // success + FollowBlockNum = IDomIndex; + break; + } } + --IDomIndex; } - --IDomIndex; } - #if 0 // If we failed, see if it was because of both branches of an if-then-else // terminating with a RETURN. A call to a function that does not return, such @@ -9237,42 +9314,79 @@ int SMPFunction::FindConditionalFollowNode(int HeadBlockNum) { int ElseBlockNum = (*(CurrBlock->GetCondNonFallThroughSucc()))->GetNumber(); assert(SMP_BLOCKNUM_UNINIT != ElseBlockNum); int ThenBlockNum = (*(CurrBlock->GetCondOtherSucc(ElseBlockNum)))->GetNumber(); - STARSBitSet ThenBlocksSeen, ElseBlocksSeen; - ThenBlocksSeen.AllocateBits(this->GetNumBlocks()); - ElseBlocksSeen.AllocateBits(this->GetNumBlocks()); - int ThenFollowBlockNum = this->TrackConditionalBranchTerminus(HeadBlockNum, ThenBlockNum, ThenBlocksSeen); - int ElseFollowBlockNum = this->TrackConditionalBranchTerminus(HeadBlockNum, ElseBlockNum, ElseBlocksSeen); - if ((SMP_BLOCKNUM_UNINIT != ThenFollowBlockNum) && (SMP_BLOCKNUM_UNINIT != ElseFollowBlockNum)) { - // No errors; compute the meet function. - if ((0 <= ThenFollowBlockNum) && (0 <= ElseFollowBlockNum)) { - if (ThenFollowBlockNum == ElseFollowBlockNum) { - // Why didn't we get this follow block from the dominator info? + assert(SMP_BLOCKNUM_UNINIT != ThenBlockNum); + + // For an if-then-else, both successors should be dominated by the branch header block. + // If one is dominated but the other is not, then the non-dominated block is the follow block + // and we just have an if-then structure, e.g. + // branch_block + // | + // +-----+ + // | | + // | | then_block + // | | | + // +--block2--+ + // + // block2 is reachable from somewhere above branch_block. We don't want to start + // at block2 and search downwards, because block2 is already the follow block for + // branch_block. + int ThenIDom = this->IDom[(size_t) ThenBlockNum]; + int ElseIDom = this->IDom[(size_t) ElseBlockNum]; + bool IfThenElseCase = ((ThenIDom == ElseIDom) && (ThenIDom == HeadBlockNum)); + if (!IfThenElseCase) { + // See if we fit the pattern above. + if (ThenIDom == HeadBlockNum) + FollowBlockNum = ElseBlockNum; + else if (ElseIDom == HeadBlockNum) + FollowBlockNum = ThenBlockNum; + else { + SMP_msg("ERROR: FindConditionalFollowNode in %s has no successors with IDom of HeadBlockNum %d\n", + this->GetFuncName(), HeadBlockNum); + FollowBlockNum = SMP_BLOCKNUM_UNINIT; // error signal + } + } + else { + STARSBitSet ThenBlocksSeen, ElseBlocksSeen; + ThenBlocksSeen.AllocateBits(this->GetNumBlocks()); + ElseBlocksSeen.AllocateBits(this->GetNumBlocks()); + int ThenFollowBlockNum = this->TrackConditionalBranchTerminus(HeadBlockNum, ThenBlockNum, ThenBlocksSeen); + int ElseFollowBlockNum = this->TrackConditionalBranchTerminus(HeadBlockNum, ElseBlockNum, ElseBlocksSeen); + if ((SMP_BLOCKNUM_UNINIT != ThenFollowBlockNum) && (SMP_BLOCKNUM_UNINIT != ElseFollowBlockNum)) { + // No errors; compute the meet function. + if ((0 <= ThenFollowBlockNum) && (0 <= ElseFollowBlockNum)) { + if (ThenFollowBlockNum == ElseFollowBlockNum) { + // Why didn't we get this follow block from the dominator info? + FollowBlockNum = ThenFollowBlockNum; + if (ShortCircuit) + SMP_msg("INFO: Got FollowBlockNum of %d for ShortCircuit block %d in %s via consistent termini.\n", + FollowBlockNum, HeadBlockNum, this->GetFuncName()); + else + SMP_msg("WARNING: Got FollowBlockNum of %d for block %d in %s via consistent termini after failing via dominator tree.\n", + FollowBlockNum, HeadBlockNum, this->GetFuncName()); + } + else { + SMP_msg("ERROR: Inconsistent if-else termini block numbers: %d and %d for branch head: %d in func %s\n", + ThenFollowBlockNum, ElseFollowBlockNum, HeadBlockNum, this->GetFuncName()); + FollowBlockNum = SMP_BLOCKNUM_UNINIT; // error signal + } + } + else if (0 <= ThenFollowBlockNum) { FollowBlockNum = ThenFollowBlockNum; - SMP_msg("WARNING: Got FollowBlockNum of %d for block %d in %s via consistent termini after failing via dominator tree.\n", + SMP_msg("INFO: Got FollowBlockNum of %d for block %d in %s via THEN terminus after failing via dominator tree.\n", FollowBlockNum, HeadBlockNum, this->GetFuncName()); } else { - SMP_msg("ERROR: Inconsistent if-else termini block numbers: %d and %d for branch head: %d in func %s\n", - ThenFollowBlockNum, ElseFollowBlockNum, HeadBlockNum, this->GetFuncName()); - FollowBlockNum = SMP_BLOCKNUM_UNINIT; // error signal + FollowBlockNum = ElseFollowBlockNum; + SMP_msg("INFO: Got FollowBlockNum of %d for block %d in %s via ELSE terminus after failing via dominator tree.\n", + FollowBlockNum, HeadBlockNum, this->GetFuncName()); } } - else if (0 <= ThenFollowBlockNum) { - FollowBlockNum = ThenFollowBlockNum; - SMP_msg("INFO: Got FollowBlockNum of %d for block %d in %s via THEN terminus after failing via dominator tree.\n", - FollowBlockNum, HeadBlockNum, this->GetFuncName()); - } else { - FollowBlockNum = ElseFollowBlockNum; - SMP_msg("INFO: Got FollowBlockNum of %d for block %d in %s via ELSE terminus after failing via dominator tree.\n", - FollowBlockNum, HeadBlockNum, this->GetFuncName()); + FollowBlockNum = SMP_BLOCKNUM_UNINIT; + SMP_msg("ERROR: No FollowBlockNum for block %d in %s due to inconsistent termini after failing via dominator tree.\n", + HeadBlockNum, this->GetFuncName()); } } - else { - FollowBlockNum = SMP_BLOCKNUM_UNINIT; - SMP_msg("WARNING: No FollowBlockNum for block %d in %s due to inconsistent termini after failing via dominator tree.\n", - HeadBlockNum, this->GetFuncName()); - } } return FollowBlockNum; @@ -11121,6 +11235,8 @@ void SMPFunction::AnalyzeLoopIterations(void) { this->LoopComparisonExprs.push_back(CurrentLoopComparisonExpr); } // assert(BIVIsLeftOp || BIVIsRightOp); // not true for BIV decrement or increment in lieu of a compare opcode + if (!(BIVIsLeftOp || BIVIsRightOp)) + continue; bool PositiveIncrement = IsPositiveIncrementBIV((*IVarVecIter).BasicInductionVar); // First, we need to find a loop-invariant initializer for the incoming value. @@ -15208,7 +15324,6 @@ bool SMPFunction::EmitSPARKLoopMemRangePostCondition(FILE *HeaderFile, FILE *Bod for (size_t RegNo = 0; RegNo < LoopPreservedRegs.size(); ++RegNo) { if (LoopPreservedRegs[RegNo]) { if (!LocalPostPrintStarted) { - SMP_fprintf(HeaderFile, "("); LocalPostPrintStarted = true; } else { @@ -15499,9 +15614,9 @@ void SMPFunction::AggregateLoopMemExprs(size_t LoopIndex) { this->TempNonRangeExprs.clear(); this->TempLowerBoundsExprs.clear(); this->TempUpperBoundsExprs.clear(); - this->RelationalMemWriteWidths.clear(); - this->RelationalLowerBoundExprs.clear(); - this->RelationalUpperBoundExprs.clear(); + this->RelationalMemWriteWidths[LoopNumPlusOne].clear(); + this->RelationalLowerBoundExprs[LoopNumPlusOne].clear(); + this->RelationalUpperBoundExprs[LoopNumPlusOne].clear(); if (this->NonStackFrameLoopMemWrites[LoopIndex]) { // not just local var write InsertResult = this->TempLowerBoundsExprs.insert(this->LoopMemWriteLowerBoundsExprs[LoopIndex]); diff --git a/src/base/SMPProgram.cpp b/src/base/SMPProgram.cpp index 05ef0e8f3a98e6f0a4e2e9bd97f2e26675ecb5da..d840c5ce4233c1e522cc012527a543cd6cef0f68 100644 --- a/src/base/SMPProgram.cpp +++ b/src/base/SMPProgram.cpp @@ -776,8 +776,8 @@ void SMPProgram::Analyze(ProfilerInformation *pi, FILE *AnnotFile, FILE *InfoAnn #endif changed |= CurrFunc->InferInterproceduralTypes(); } -#if 1 - if ((!changed || (IterationCounter > STARS_INTERPROCEDURAL_ITERATION_LIMIT)) && (0 == strcmp("sha_update", CurrFunc->GetFuncName()))) { +#if 0 + if ((!changed || (IterationCounter > STARS_INTERPROCEDURAL_ITERATION_LIMIT)) && (0 == strcmp("__mktime_internal", CurrFunc->GetFuncName()))) { CurrFunc->Dump(); } #endif @@ -1030,9 +1030,8 @@ bool SMPProgram::EmitProgramSPARKAda(void) { SMP_fprintf(BodyFile, "procedure %s is\nbegin\n\tX86.RSP := X86.RSP + %u;\n", TempFunc->GetFuncName(), ByteWidth); SMP_fprintf(BodyFile, "end %s;\n\n", TempFunc->GetFuncName()); - if (0 == strcmp("main", TempFunc->GetFuncName())) { + // if (0 == strcmp("main", TempFunc->GetFuncName())) TempFunc->Dump(); - } } } } // end for all functions