// Tries to remove a sanity check; returns true if it worked. bool AsapPass::optimizeCheckAway(llvm::Instruction *Inst) { BranchInst *BI = cast<BranchInst>(Inst); assert(BI->isConditional() && "Sanity check must be conditional branch."); unsigned int RegularBranch = getRegularBranch(BI, SCI); bool Changed = false; if (RegularBranch == 0) { BI->setCondition(ConstantInt::getTrue(Inst->getContext())); Changed = true; } else if (RegularBranch == 1) { BI->setCondition(ConstantInt::getFalse(Inst->getContext())); Changed = true; } else { // This can happen, e.g., in the following case: // array[-1] = a + b; // is transformed into // if (a + b overflows) // report_overflow() // else // report_index_out_of_bounds(); // In this case, removing the sanity check does not help much, so we // just do nothing. // Thanks to Will Dietz for his explanation at // http://lists.cs.uiuc.edu/pipermail/llvmdev/2014-April/071958.html dbgs() << "Warning: Sanity check with no regular branch found.\n"; dbgs() << "The sanity check has been kept intact.\n"; } if (PrintRemovedChecks && Changed) { DebugLoc DL = getSanityCheckDebugLoc(BI, RegularBranch); printDebugLoc(DL, BI->getContext(), dbgs()); dbgs() << ": SanityCheck with cost "; dbgs() << *BI->getMetadata("cost")->getOperand(0); if (MDNode *IA = DL.getInlinedAt()) { dbgs() << " (inlined at "; printDebugLoc(DebugLoc(IA), BI->getContext(), dbgs()); dbgs() << ")"; } BasicBlock *Succ = BI->getSuccessor(RegularBranch == 0 ? 1 : 0); if (const CallInst *CI = SCI->findSanityCheckCall(Succ)) { dbgs() << " " << CI->getCalledFunction()->getName(); } dbgs() << "\n"; } return Changed; }
void Executor::executeBranch(Instruction *i, bool cond) { assert(i && "Expecting an instruction!"); LastExecutedBB = i->getParent(); if (CollectBlockTraces) { ExecutedBlocks.push_back(LastExecutedBB); } BranchInst *br = dyn_cast<BranchInst>(i); if (br->isConditional()) { // Loops: check if the control-flow // jump back to a loop header. std::string bbname = PathLoopInfo->getLoopLatchName(br); BasicBlock *nextBB1 = br->getSuccessor(0); BasicBlock *nextBB2 = br->getSuccessor(1); if ((cond && bbname==nextBB1->getName().str()) || (!cond && bbname==nextBB2->getName().str())) { unsigned line = 0; if (MDNode *N = br->getMetadata("dbg")) { DILocation Loc(N); line = Loc.getLineNumber(); } //std::cout << "Current: " << LastExecutedBB->getName().str() << std::endl; //std::cout << "LoopLatch: " << bbname << std::endl; std::cout << "Violated property: unwinding assertion"; std::cout << " (line " << line << ")\n"; //exit(1); DisabledSymbolicExeCurRun = true; return; } // Next block to be executed if (cond) { NextBB = nextBB1; } else { NextBB = nextBB2; } } else { // Next block to be executed NextBB = br->getSuccessor(0); } if (!DisabledSymbolicExeCurRun) { PathContext->propagatePointers(LastExecutedBB, NextBB); } // For program coverage analysis //Profile->covered(br, cond); //Profile->covered(br->getParent()); if(br->isConditional()) { // Update the number of time we jump in the IR GotoCount++; if (GotoCount>MaxDepth) { std::cout << "warning: maximum goto-count ("; std::cout << GotoCount << ") reached.\n"; DisabledSymbolicExeCurRun = true; return; } if (DisabledSymbolicExeCurRun) { return; } Value *vcond = br->getCondition(); // vcond in domain(S) if (SMAP->contains(vcond)) { SymbolPtr Svcond = SMAP->get(vcond); // Report(S(vcond), branchTaken) Path->addBranchCell(Svcond, cond, i); } } }