bool CallAnalyzer::visitBranchInst(BranchInst &BI) { // We model unconditional branches as essentially free -- they really // shouldn't exist at all, but handling them makes the behavior of the // inliner more regular and predictable. Interestingly, conditional branches // which will fold away are also free. return BI.isUnconditional() || isa<ConstantInt>(BI.getCondition()) || dyn_cast_or_null<ConstantInt>( SimplifiedValues.lookup(BI.getCondition())); }
int BranchProbabilities::CheckFloatHeuristic() { // Heuristic fails if the last instruction is not a conditional branch BranchInst *BI = dyn_cast<BranchInst>(_TI); if ((!BI) || (BI->isUnconditional())) return -1; // All float comparisons are done with the fcmp instruction FCmpInst *fcmp = dyn_cast<FCmpInst>(BI->getCondition()); if (!fcmp) return -1; // Choose the prefered branch depending on if this is an eq or neq comp switch (fcmp->getPredicate()) { case FCmpInst::FCMP_OEQ: case FCmpInst::FCMP_UEQ: return 1; case FCmpInst::FCMP_ONE: case FCmpInst::FCMP_UNE: return 0; case FCmpInst::FCMP_FALSE: case FCmpInst::FCMP_TRUE: assert("true or false predicate should have been folded!"); default: return -1; } }
bool BranchProbabilityInfo::calcFloatingPointHeuristics(BasicBlock *BB) { BranchInst *BI = dyn_cast<BranchInst>(BB->getTerminator()); if (!BI || !BI->isConditional()) return false; Value *Cond = BI->getCondition(); FCmpInst *FCmp = dyn_cast<FCmpInst>(Cond); if (!FCmp) return false; bool isProb; if (FCmp->isEquality()) { // f1 == f2 -> Unlikely // f1 != f2 -> Likely isProb = !FCmp->isTrueWhenEqual(); } else if (FCmp->getPredicate() == FCmpInst::FCMP_ORD) { // !isnan -> Likely isProb = true; } else if (FCmp->getPredicate() == FCmpInst::FCMP_UNO) { // isnan -> Unlikely isProb = false; } else { return false; } unsigned TakenIdx = 0, NonTakenIdx = 1; if (!isProb) std::swap(TakenIdx, NonTakenIdx); setEdgeWeight(BB, TakenIdx, FPH_TAKEN_WEIGHT); setEdgeWeight(BB, NonTakenIdx, FPH_NONTAKEN_WEIGHT); return true; }
///////////////////////////////////// //findLastSyn() // //Find the last instruction in BB. Any instructions before this one must be replicated except Synchpoint ///////////////////////////////////// Instruction* InsDuplica::findLastCond (BasicBlock *BB) { TerminatorInst *lastIns = BB->getTerminator(); assert(!(isa<SwitchInst>(lastIns)) && "Find a SwitchInst! You need to lower SwitchInst."); BranchInst * BI = dyn_cast<BranchInst>(lastIns); if (BI && (BI->isConditional())) { Value *cond = BI->getCondition(); Instruction* condIns = dyn_cast<Instruction>(cond); //find condIns. But we have to make sure condIns is the second to the last instruction in BB assert(condIns && "Branch Condition must not be trivial"); if ((condIns->getNextNode())!=lastIns) { //assert((condIns->getParent() == BB) && "condIns is not in the same BB as br!"); //if condIns is not in the same BB as br. We have to leave it there if (condIns->getParent() != BB) return lastIns; //if condIns is a PHINode, since we can not move, we just return BI //if condIns has more than one use, better not to reorder if ((isa<PHINode>(condIns))||!(condIns->hasOneUse())) return lastIns; condIns->moveBefore(lastIns); //we moved condInst right before br #ifdef Jing_DEBUG std::cerr << "adjust order of condIns "<< condIns->getName() <<" in " << BB->getName() <<"\n"; #endif } #ifdef Jing_DEBUG std::cerr << "findLastCond returns " << condIns->getName() <<"\n"; #endif return condIns; } //return the terminator instruction return lastIns; }
void TempScopInfo::buildCondition(BasicBlock *BB, BasicBlock *RegionEntry) { BBCond Cond; DomTreeNode *BBNode = DT->getNode(BB), *EntryNode = DT->getNode(RegionEntry); assert(BBNode && EntryNode && "Get null node while building condition!"); // Walk up the dominance tree until reaching the entry node. Add all // conditions on the path to BB except if BB postdominates the block // containing the condition. while (BBNode != EntryNode) { BasicBlock *CurBB = BBNode->getBlock(); BBNode = BBNode->getIDom(); assert(BBNode && "BBNode should not reach the root node!"); if (PDT->dominates(CurBB, BBNode->getBlock())) continue; BranchInst *Br = dyn_cast<BranchInst>(BBNode->getBlock()->getTerminator()); assert(Br && "A Valid Scop should only contain branch instruction"); if (Br->isUnconditional()) continue; // Is BB on the ELSE side of the branch? bool inverted = DT->dominates(Br->getSuccessor(1), BB); Comparison *Cmp; buildAffineCondition(*(Br->getCondition()), inverted, &Cmp); Cond.push_back(*Cmp); } if (!Cond.empty()) BBConds[BB] = Cond; }
void MakeDispatcherPass::ConvertCmp(Function& function) { typedef std::vector< Instruction * > InstList; InstList insts; for (Function::iterator BB = function.begin(), bbE = function.end(); BB != bbE; ++BB) { for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E;) { if (isa< CmpInst >(I)) { insts.push_back(I); } if (isa< BranchInst >(I)) { BasicBlock::iterator save = I; BranchInst* branchInst = dynamic_cast< BranchInst *>(&*I); if (branchInst->isConditional() && !insts.empty()) { Value* valbranch = NULL; valbranch = branchInst->getCondition(); ShowType(dynamic_cast<CmpInst*>(insts[0])); CreateInt3(BB, I); I++; save->eraseFromParent(); insts.pop_back(); continue; } } I++; } } }
//It receives a BasicBLock and makes table of predicates and its respective gated instructions void bSSA::makeTable (BasicBlock *BB, Function *F) { Value *condition; TerminatorInst *ti = BB->getTerminator(); BranchInst *bi = NULL; SwitchInst *si=NULL; PostDominatorTree &PD = getAnalysis<PostDominatorTree>(*F); ProcessedBB.clear(); if ((bi = dyn_cast<BranchInst>(ti)) && bi->isConditional()) { //If the terminator instruction is a conditional branch condition = bi->getCondition(); //Including the predicate on the predicatesVector predicatesVector.push_back(new Pred(condition)); //Make a "Flooding" on each sucessor gated the instruction on Influence Region of the predicate for (unsigned int i=0; i<bi->getNumSuccessors(); i++) { findIR (BB, bi->getSuccessor(i),PD); } }else if ((si = dyn_cast<SwitchInst>(ti))) { condition = si->getCondition(); //Including the predicate on the predicatesVector predicatesVector.push_back(new Pred(condition)); //Make a "Flooding" on each sucessor gated the instruction on Influence Region of the predicate for (unsigned int i=0; i<si->getNumSuccessors(); i++) { findIR (BB, si->getSuccessor(i),PD); } } }
bool BranchProbabilityAnalysis::calcZeroHeuristics(BasicBlock *BB) { BranchInst * BI = dyn_cast<BranchInst>(BB->getTerminator()); if (!BI || !BI->isConditional()) return false; Value *Cond = BI->getCondition(); ICmpInst *CI = dyn_cast<ICmpInst>(Cond); if (!CI) return false; Value *RHS = CI->getOperand(1); ConstantInt *CV = dyn_cast<ConstantInt>(RHS); if (!CV) return false; bool isProb; if (CV->isZero()) { switch (CI->getPredicate()) { case CmpInst::ICMP_EQ: // X == 0 -> Unlikely isProb = false; break; case CmpInst::ICMP_NE: // X != 0 -> Likely isProb = true; break; case CmpInst::ICMP_SLT: // X < 0 -> Unlikely isProb = false; break; case CmpInst::ICMP_SGT: // X > 0 -> Likely isProb = true; break; default: return false; } } else if (CV->isOne() && CI->getPredicate() == CmpInst::ICMP_SLT) { // InstCombine canonicalizes X <= 0 into X < 1. // X <= 0 -> Unlikely isProb = false; } else if (CV->isAllOnesValue() && CI->getPredicate() == CmpInst::ICMP_SGT) { // InstCombine canonicalizes X >= 0 into X > -1. // X >= 0 -> Likely isProb = true; } else { return false; } BasicBlock *Taken = BI->getSuccessor(0); BasicBlock *NonTaken = BI->getSuccessor(1); if (!isProb) std::swap(Taken, NonTaken); BP->setEdgeWeight(BB, Taken, ZH_TAKEN_WEIGHT); BP->setEdgeWeight(BB, NonTaken, ZH_NONTAKEN_WEIGHT); return true; }
// Calculate Edge Weights using "Pointer Heuristics". Predict a comparsion // between two pointer or pointer and NULL will fail. bool BranchProbabilityInfo::calcPointerHeuristics(BasicBlock *BB) { BranchInst * BI = dyn_cast<BranchInst>(BB->getTerminator()); if (!BI || !BI->isConditional()) return false; Value *Cond = BI->getCondition(); ICmpInst *CI = dyn_cast<ICmpInst>(Cond); if (!CI || !CI->isEquality()) return false; Value *LHS = CI->getOperand(0); if (!LHS->getType()->isPointerTy()) return false; assert(CI->getOperand(1)->getType()->isPointerTy()); // p != 0 -> isProb = true // p == 0 -> isProb = false // p != q -> isProb = true // p == q -> isProb = false; unsigned TakenIdx = 0, NonTakenIdx = 1; bool isProb = CI->getPredicate() == ICmpInst::ICMP_NE; if (!isProb) std::swap(TakenIdx, NonTakenIdx); setEdgeWeight(BB, TakenIdx, PH_TAKEN_WEIGHT); setEdgeWeight(BB, NonTakenIdx, PH_NONTAKEN_WEIGHT); return true; }
// Look for control dependencies on a read. bool branchesOn(BasicBlock *bb, Value *load, ICmpInst **icmpOut, int *outIdx) { // XXX: make this platform configured; on some platforms maybe an // atomic cmpxchg does /not/ behave like it branches on the old value if (isa<AtomicCmpXchgInst>(load) || isa<AtomicRMWInst>(load)) { if (icmpOut) *icmpOut = nullptr; if (outIdx) *outIdx = 0; return true; } // TODO: we should be able to follow values through phi nodes, // since we are path dependent anyways. BranchInst *br = dyn_cast<BranchInst>(bb->getTerminator()); if (!br || !br->isConditional()) return false; // TODO: We only check one level of things. Check deeper? // We pretty heavily restrict what operations we handle here. // Some would just be wrong (like call), but really icmp is // the main one, so. Probably we should be able to also // pick through casts and wideness changes. ICmpInst *icmp = dyn_cast<ICmpInst>(br->getCondition()); if (!icmp) return false; int idx = 0; for (auto v : icmp->operand_values()) { if (getRealValue(v) == load) { if (icmpOut) *icmpOut = icmp; if (outIdx) *outIdx = idx; return true; } ++idx; } return false; }
void AMDGPUAnnotateUniformValues::visitBranchInst(BranchInst &I) { if (I.isUnconditional()) return; Value *Cond = I.getCondition(); if (!DA->isUniform(Cond)) return; setUniformMetadata(I.getParent()->getTerminator()); }
bool BranchProbabilityAnalysis::calcZeroHeuristics(BasicBlock *BB) { BranchInst * BI = dyn_cast<BranchInst>(BB->getTerminator()); if (!BI || !BI->isConditional()) return false; Value *Cond = BI->getCondition(); ICmpInst *CI = dyn_cast<ICmpInst>(Cond); if (!CI) return false; Value *RHS = CI->getOperand(1); ConstantInt *CV = dyn_cast<ConstantInt>(RHS); if (!CV || !CV->isZero()) return false; bool isProb; switch (CI->getPredicate()) { case CmpInst::ICMP_EQ: // Equal to zero is not expected to be taken. isProb = false; break; case CmpInst::ICMP_NE: // Not equal to zero is expected. isProb = true; break; case CmpInst::ICMP_SLT: // Less or equal to zero is not expected. // X < 0 -> Unlikely isProb = false; break; case CmpInst::ICMP_UGT: case CmpInst::ICMP_SGT: // Greater or equal to zero is expected. // X > 0 -> Likely isProb = true; break; default: return false; }; BasicBlock *Taken = BI->getSuccessor(0); BasicBlock *NonTaken = BI->getSuccessor(1); if (!isProb) std::swap(Taken, NonTaken); BP->setEdgeWeight(BB, Taken, ZH_TAKEN_WEIGHT); BP->setEdgeWeight(BB, NonTaken, ZH_NONTAKEN_WEIGHT); return true; }
bool IRTranslator::translateBr(const BranchInst &BrInst) { unsigned Succ = 0; if (!BrInst.isUnconditional()) { // We want a G_BRCOND to the true BB followed by an unconditional branch. unsigned Tst = getOrCreateVReg(*BrInst.getCondition()); const BasicBlock &TrueTgt = *cast<BasicBlock>(BrInst.getSuccessor(Succ++)); MachineBasicBlock &TrueBB = getOrCreateBB(TrueTgt); MIRBuilder.buildBrCond(LLT{*BrInst.getCondition()->getType()}, Tst, TrueBB); } const BasicBlock &BrTgt = *cast<BasicBlock>(BrInst.getSuccessor(Succ)); MachineBasicBlock &TgtBB = getOrCreateBB(BrTgt); MIRBuilder.buildBr(TgtBB); // Link successors. MachineBasicBlock &CurBB = MIRBuilder.getMBB(); for (const BasicBlock *Succ : BrInst.successors()) CurBB.addSuccessor(&getOrCreateBB(*Succ)); return true; }
void Interpreter::visitBranchInst(BranchInst &I) { ExecutionContext &SF = ECStack.back(); BasicBlock *Dest; Dest = I.getSuccessor(0); // Uncond branches have a fixed dest... if (!I.isUnconditional()) { Value *Cond = I.getCondition(); if (getOperandValue(Cond, SF).BoolVal == 0) // If false cond... Dest = I.getSuccessor(1); } SwitchToNewBasicBlock(Dest, SF); }
void Graph::DFS2_visit(DFSNode * DFS) { DFS->C = GRAY; if (DFS->T == UNKNOWN){ Instruction *I = dynamic_cast<Instruction *>(DFS->Bb->getTerminator()); BranchInst *BI = static_cast<BranchInst *>(I); if (BI->isConditional()){ //branchmap[BI] = dfs->bb; BranchMap[BI->getCondition()] = DFS->Bb; if (TypeStack.empty()) DFS->T = IF; else if (TypeStack.top() != ENDIF) DFS->T = IF; //else if (TypeStack.top() == ENDIF && Time == DFS->DTime - 2) // DFS->T = ELSEIF; else if (DFS->Bb->getName().substr(0,7) == "if.else") DFS->T = ELSEIF; //else if (TypeStack.top() == ELSEIF) // DFS->T = ELSEIF; else if(TypeStack.top() == ENDIF && (Time != DFS->DTime - 1)) DFS->T = IF; else DEBUG (errs() << "\n\n\n\n\n\n\nError at: " << " Top = " << TypeStack.top() << " Time = " << Time << " DTime = " << DFS->DTime << "\n\n\n\n\n\n\n\n\n"); } else { DEBUG (errs() << "Bb: " <<DFS->Bb << " is not conditional\n"); } } if (DFS->T != UNKNOWN){ Time = DFS->DTime; TypeStack.push(DFS->T); DEBUG (errs() << "Stack: " << TypeStack.top() <<'\n'); } DEBUG (errs() << "Type of: " << DFS->Bb << " is: " << DFS->T << " global time: " << Time << " dfstime: " << DFS->DTime << '\n'); // for each vector adjacent to dfs std::vector<DFSNode *> Svec = DFS->Vertex; for (std::vector<DFSNode *>::iterator It = Svec.begin(); It != Svec.end(); ++It) { DFSNode *DN = *It; if (DN->C == WHITE) DFS2_visit(DN); } DFS->C = BLACK; if (DFS->T != UNKNOWN) Time = DFS->FTime; }
// Predict that a comparison in which a register is an operand, the register is // used before being defined in a successor block, and the successor block // does not post-dominate will reach the successor block. int BranchProbabilities::CheckGuardHeuristic() { BranchInst *BI = dyn_cast<BranchInst>(_TI); bool bUses[2] = {false, false}; // If we don't have a conditional branch, abandon if ((!BI) || (BI->isUnconditional())) return -1; // If the condition is not immediately dependent on a comparison, abandon CmpInst *cmp = dyn_cast<CmpInst>(BI->getCondition()); if (!cmp) return -1; for (int i = 0; i < 2; i++) { if (_bPostDoms[i]) continue; // Get the values being compared Value *v = cmp->getOperand(i); // For all uses of the first value check if the use post-dominates for (Value::use_iterator UI = v->use_begin(), UE = v->use_end(); UI != UE; ++UI) { // if the use is not an instruction, skip it Instruction *I = dyn_cast<Instruction>(*UI); if (!I) continue; BasicBlock *UsingBlock = I->getParent(); // Check if the use is in either successor for (int i = 0; i < 2; i++) if (UsingBlock == _Succ[i]) bUses[i] = true; } } if (bUses[0] == bUses[1]) return -1; if (bUses[0]) return 0; else return 1; }
/// Annotate the control flow with intrinsics so the backend can /// recognize if/then/else and loops. bool SIAnnotateControlFlow::runOnFunction(Function &F) { DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree(); LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo(); DA = &getAnalysis<LegacyDivergenceAnalysis>(); for (df_iterator<BasicBlock *> I = df_begin(&F.getEntryBlock()), E = df_end(&F.getEntryBlock()); I != E; ++I) { BasicBlock *BB = *I; BranchInst *Term = dyn_cast<BranchInst>(BB->getTerminator()); if (!Term || Term->isUnconditional()) { if (isTopOfStack(BB)) closeControlFlow(BB); continue; } if (I.nodeVisited(Term->getSuccessor(1))) { if (isTopOfStack(BB)) closeControlFlow(BB); handleLoop(Term); continue; } if (isTopOfStack(BB)) { PHINode *Phi = dyn_cast<PHINode>(Term->getCondition()); if (Phi && Phi->getParent() == BB && isElse(Phi)) { insertElse(Term); eraseIfUnused(Phi); continue; } closeControlFlow(BB); } openIf(Term); } if (!Stack.empty()) { // CFG was probably not structured. report_fatal_error("failed to annotate CFG"); } return true; }
/// MatchPointerHeuristic - Predict that a comparison of a pointer against /// null or of two pointers will fail. /// @returns a Prediction that is a pair in which the first element is the /// successor taken, and the second the successor not taken. Prediction BranchHeuristicsInfo::MatchPointerHeuristic(BasicBlock *root) const { // Last instruction of basic block. TerminatorInst *TI = root->getTerminator(); // Basic block successors. True and False branches. BasicBlock *trueSuccessor = TI->getSuccessor(0); BasicBlock *falseSuccessor = TI->getSuccessor(1); // Is the last instruction a Branch Instruction? BranchInst *BI = dyn_cast<BranchInst>(TI); if (!BI || !BI->isConditional()) return empty; // Conditional instruction. Value *cond = BI->getCondition(); // Pointer comparisons are integer comparisons. ICmpInst *II = dyn_cast<ICmpInst>(cond); if (!II) return empty; // An integer comparison has always two operands. Value *operand1 = II->getOperand(0); Value *operand2 = II->getOperand(1); // Obtain the type of comparison. enum ICmpInst::Predicate signedPred = II->getSignedPredicate(); // The heuristic states that it must be compared against null, // but in LLVM, null is also a PointerType, so it only requires // to test if there is a comparison between two pointers. if (signedPred == ICmpInst::ICMP_EQ && isa<PointerType>(operand1->getType()) && // NULL is a pointer type too isa<PointerType>(operand2->getType())) { // NULL is a pointer type too return std::make_pair(falseSuccessor, trueSuccessor); } else if (signedPred != ICmpInst::ICMP_EQ && isa<PointerType>(operand1->getType()) && isa<PointerType>(operand2->getType())) { return std::make_pair(trueSuccessor, falseSuccessor); } return empty; }
/// \brief Annotate the control flow with intrinsics so the backend can /// recognize if/then/else and loops. bool SIAnnotateControlFlow::runOnFunction(Function &F) { DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree(); LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo(); DA = &getAnalysis<DivergenceAnalysis>(); for (df_iterator<BasicBlock *> I = df_begin(&F.getEntryBlock()), E = df_end(&F.getEntryBlock()); I != E; ++I) { BranchInst *Term = dyn_cast<BranchInst>((*I)->getTerminator()); if (!Term || Term->isUnconditional()) { if (isTopOfStack(*I)) closeControlFlow(*I); continue; } if (I.nodeVisited(Term->getSuccessor(1))) { if (isTopOfStack(*I)) closeControlFlow(*I); handleLoop(Term); continue; } if (isTopOfStack(*I)) { PHINode *Phi = dyn_cast<PHINode>(Term->getCondition()); if (Phi && Phi->getParent() == *I && isElse(Phi)) { insertElse(Term); eraseIfUnused(Phi); continue; } closeControlFlow(*I); } openIf(Term); } assert(Stack.empty()); return true; }
int BranchProbabilities::CheckPointerHeuristic() { // Heuristic fails if the last instruction is not a conditional branch BranchInst *BI = dyn_cast<BranchInst>(_TI); if ((!BI) || (BI->isUnconditional())) return -1; // All pointer comparisons are done with the icmp instruction ICmpInst *icmp = dyn_cast<ICmpInst>(BI->getCondition()); if (!icmp) return -1; Value *v[2]; v[0] = icmp->getOperand(0); v[1] = icmp->getOperand(1); // Make sure we're comparing pointers if (isa<PointerType>(v[0]->getType())) { assert(isa<PointerType>(v[1]->getType()) && "v[1] is not a pointer!"); // Choose the prefered branch depending on if this is an eq or neq comp switch (icmp->getPredicate()) { case ICmpInst::ICMP_EQ: return 1; case ICmpInst::ICMP_NE: return 0; default: assert("non-equality comparison of pointers"); return -1; } } return -1; }
bool BranchProbabilityInfo::calcZeroHeuristics(BasicBlock *BB) { BranchInst * BI = dyn_cast<BranchInst>(BB->getTerminator()); if (!BI || !BI->isConditional()) return false; Value *Cond = BI->getCondition(); ICmpInst *CI = dyn_cast<ICmpInst>(Cond); if (!CI) return false; Value *RHS = CI->getOperand(1); ConstantInt *CV = dyn_cast<ConstantInt>(RHS); if (!CV) return false; // If the LHS is the result of AND'ing a value with a single bit bitmask, // we don't have information about probabilities. if (Instruction *LHS = dyn_cast<Instruction>(CI->getOperand(0))) if (LHS->getOpcode() == Instruction::And) if (ConstantInt *AndRHS = dyn_cast<ConstantInt>(LHS->getOperand(1))) if (AndRHS->getUniqueInteger().isPowerOf2()) return false; bool isProb; if (CV->isZero()) { switch (CI->getPredicate()) { case CmpInst::ICMP_EQ: // X == 0 -> Unlikely isProb = false; break; case CmpInst::ICMP_NE: // X != 0 -> Likely isProb = true; break; case CmpInst::ICMP_SLT: // X < 0 -> Unlikely isProb = false; break; case CmpInst::ICMP_SGT: // X > 0 -> Likely isProb = true; break; default: return false; } } else if (CV->isOne() && CI->getPredicate() == CmpInst::ICMP_SLT) { // InstCombine canonicalizes X <= 0 into X < 1. // X <= 0 -> Unlikely isProb = false; } else if (CV->isAllOnesValue()) { switch (CI->getPredicate()) { case CmpInst::ICMP_EQ: // X == -1 -> Unlikely isProb = false; break; case CmpInst::ICMP_NE: // X != -1 -> Likely isProb = true; break; case CmpInst::ICMP_SGT: // InstCombine canonicalizes X >= 0 into X > -1. // X >= 0 -> Likely isProb = true; break; default: return false; } } else { return false; } unsigned TakenIdx = 0, NonTakenIdx = 1; if (!isProb) std::swap(TakenIdx, NonTakenIdx); BranchProbability TakenProb(ZH_TAKEN_WEIGHT, ZH_TAKEN_WEIGHT + ZH_NONTAKEN_WEIGHT); setEdgeProbability(BB, TakenIdx, TakenProb); setEdgeProbability(BB, NonTakenIdx, TakenProb.getCompl()); return true; }
bool ScopDetection::isValidCFG(BasicBlock &BB, DetectionContext &Context) const { Region &RefRegion = Context.CurRegion; TerminatorInst *TI = BB.getTerminator(); // Return instructions are only valid if the region is the top level region. if (isa<ReturnInst>(TI) && !RefRegion.getExit() && TI->getNumOperands() == 0) return true; BranchInst *Br = dyn_cast<BranchInst>(TI); if (!Br) return invalid<ReportNonBranchTerminator>(Context, /*Assert=*/true, &BB); if (Br->isUnconditional()) return true; Value *Condition = Br->getCondition(); // UndefValue is not allowed as condition. if (isa<UndefValue>(Condition)) return invalid<ReportUndefCond>(Context, /*Assert=*/true, &BB); // Only Constant and ICmpInst are allowed as condition. if (!(isa<Constant>(Condition) || isa<ICmpInst>(Condition))) return invalid<ReportInvalidCond>(Context, /*Assert=*/true, &BB); // Allow perfectly nested conditions. assert(Br->getNumSuccessors() == 2 && "Unexpected number of successors"); if (ICmpInst *ICmp = dyn_cast<ICmpInst>(Condition)) { // Unsigned comparisons are not allowed. They trigger overflow problems // in the code generation. // // TODO: This is not sufficient and just hides bugs. However it does pretty // well. if (ICmp->isUnsigned()) return false; // Are both operands of the ICmp affine? if (isa<UndefValue>(ICmp->getOperand(0)) || isa<UndefValue>(ICmp->getOperand(1))) return invalid<ReportUndefOperand>(Context, /*Assert=*/true, &BB); Loop *L = LI->getLoopFor(ICmp->getParent()); const SCEV *LHS = SE->getSCEVAtScope(ICmp->getOperand(0), L); const SCEV *RHS = SE->getSCEVAtScope(ICmp->getOperand(1), L); if (!isAffineExpr(&Context.CurRegion, LHS, *SE) || !isAffineExpr(&Context.CurRegion, RHS, *SE)) return invalid<ReportNonAffBranch>(Context, /*Assert=*/true, &BB, LHS, RHS); } // Allow loop exit conditions. Loop *L = LI->getLoopFor(&BB); if (L && L->getExitingBlock() == &BB) return true; // Allow perfectly nested conditions. Region *R = RI->getRegionFor(&BB); if (R->getEntry() != &BB) return invalid<ReportCondition>(Context, /*Assert=*/true, &BB); return true; }
bool LoopIndexSplit::splitLoop() { SplitCondition = NULL; if (ExitCondition->getPredicate() == ICmpInst::ICMP_NE || ExitCondition->getPredicate() == ICmpInst::ICMP_EQ) return false; BasicBlock *Header = L->getHeader(); BasicBlock *Latch = L->getLoopLatch(); BranchInst *SBR = NULL; // Split Condition Branch BranchInst *EBR = cast<BranchInst>(ExitCondition->getParent()->getTerminator()); // If Exiting block includes loop variant instructions then this // loop may not be split safely. BasicBlock *ExitingBlock = ExitCondition->getParent(); if (!cleanBlock(ExitingBlock)) return false; LLVMContext &Context = Header->getContext(); for (Loop::block_iterator I = L->block_begin(), E = L->block_end(); I != E; ++I) { BranchInst *BR = dyn_cast<BranchInst>((*I)->getTerminator()); if (!BR || BR->isUnconditional()) continue; ICmpInst *CI = dyn_cast<ICmpInst>(BR->getCondition()); if (!CI || CI == ExitCondition || CI->getPredicate() == ICmpInst::ICMP_NE || CI->getPredicate() == ICmpInst::ICMP_EQ) continue; // Unable to handle triangle loops at the moment. // In triangle loop, split condition is in header and one of the // the split destination is loop latch. If split condition is EQ // then such loops are already handle in processOneIterationLoop(). if (Header == (*I) && (Latch == BR->getSuccessor(0) || Latch == BR->getSuccessor(1))) continue; // If the block does not dominate the latch then this is not a diamond. // Such loop may not benefit from index split. if (!DT->dominates((*I), Latch)) continue; // If split condition branches heads do not have single predecessor, // SplitCondBlock, then is not possible to remove inactive branch. if (!BR->getSuccessor(0)->getSinglePredecessor() || !BR->getSuccessor(1)->getSinglePredecessor()) return false; // If the merge point for BR is not loop latch then skip this condition. if (BR->getSuccessor(0) != Latch) { DominanceFrontier::iterator DF0 = DF->find(BR->getSuccessor(0)); assert (DF0 != DF->end() && "Unable to find dominance frontier"); if (!DF0->second.count(Latch)) continue; } if (BR->getSuccessor(1) != Latch) { DominanceFrontier::iterator DF1 = DF->find(BR->getSuccessor(1)); assert (DF1 != DF->end() && "Unable to find dominance frontier"); if (!DF1->second.count(Latch)) continue; } SplitCondition = CI; SBR = BR; break; } if (!SplitCondition) return false; // If the predicate sign does not match then skip. if (ExitCondition->isSigned() != SplitCondition->isSigned()) return false; unsigned EVOpNum = (ExitCondition->getOperand(1) == IVExitValue); unsigned SVOpNum = IVBasedValues.count(SplitCondition->getOperand(0)); Value *SplitValue = SplitCondition->getOperand(SVOpNum); if (!L->isLoopInvariant(SplitValue)) return false; if (!IVBasedValues.count(SplitCondition->getOperand(!SVOpNum))) return false; // Normalize loop conditions so that it is easier to calculate new loop // bounds. if (IVisGT(*ExitCondition) || IVisGE(*ExitCondition)) { ExitCondition->setPredicate(ExitCondition->getInversePredicate()); BasicBlock *T = EBR->getSuccessor(0); EBR->setSuccessor(0, EBR->getSuccessor(1)); EBR->setSuccessor(1, T); } if (IVisGT(*SplitCondition) || IVisGE(*SplitCondition)) { SplitCondition->setPredicate(SplitCondition->getInversePredicate()); BasicBlock *T = SBR->getSuccessor(0); SBR->setSuccessor(0, SBR->getSuccessor(1)); SBR->setSuccessor(1, T); } //[*] Calculate new loop bounds. Value *AEV = SplitValue; Value *BSV = SplitValue; bool Sign = SplitCondition->isSigned(); Instruction *PHTerm = L->getLoopPreheader()->getTerminator(); if (IVisLT(*ExitCondition)) { if (IVisLT(*SplitCondition)) { /* Do nothing */ } else if (IVisLE(*SplitCondition)) { AEV = getPlusOne(SplitValue, Sign, PHTerm, Context); BSV = getPlusOne(SplitValue, Sign, PHTerm, Context); } else { assert (0 && "Unexpected split condition!"); } } else if (IVisLE(*ExitCondition)) { if (IVisLT(*SplitCondition)) { AEV = getMinusOne(SplitValue, Sign, PHTerm, Context); } else if (IVisLE(*SplitCondition)) { BSV = getPlusOne(SplitValue, Sign, PHTerm, Context); } else { assert (0 && "Unexpected split condition!"); } } else { assert (0 && "Unexpected exit condition!"); } AEV = getMin(AEV, IVExitValue, Sign, PHTerm); BSV = getMax(BSV, IVStartValue, Sign, PHTerm); // [*] Clone Loop DenseMap<const Value *, Value *> ValueMap; Loop *BLoop = CloneLoop(L, LPM, LI, ValueMap, this); Loop *ALoop = L; // [*] ALoop's exiting edge enters BLoop's header. // ALoop's original exit block becomes BLoop's exit block. PHINode *B_IndVar = cast<PHINode>(ValueMap[IndVar]); BasicBlock *A_ExitingBlock = ExitCondition->getParent(); BranchInst *A_ExitInsn = dyn_cast<BranchInst>(A_ExitingBlock->getTerminator()); assert (A_ExitInsn && "Unable to find suitable loop exit branch"); BasicBlock *B_ExitBlock = A_ExitInsn->getSuccessor(1); BasicBlock *B_Header = BLoop->getHeader(); if (ALoop->contains(B_ExitBlock)) { B_ExitBlock = A_ExitInsn->getSuccessor(0); A_ExitInsn->setSuccessor(0, B_Header); } else A_ExitInsn->setSuccessor(1, B_Header); // [*] Update ALoop's exit value using new exit value. ExitCondition->setOperand(EVOpNum, AEV); // [*] Update BLoop's header phi nodes. Remove incoming PHINode's from // original loop's preheader. Add incoming PHINode values from // ALoop's exiting block. Update BLoop header's domiantor info. // Collect inverse map of Header PHINodes. DenseMap<Value *, Value *> InverseMap; for (BasicBlock::iterator BI = ALoop->getHeader()->begin(), BE = ALoop->getHeader()->end(); BI != BE; ++BI) { if (PHINode *PN = dyn_cast<PHINode>(BI)) { PHINode *PNClone = cast<PHINode>(ValueMap[PN]); InverseMap[PNClone] = PN; } else break; } BasicBlock *A_Preheader = ALoop->getLoopPreheader(); for (BasicBlock::iterator BI = B_Header->begin(), BE = B_Header->end(); BI != BE; ++BI) { if (PHINode *PN = dyn_cast<PHINode>(BI)) { // Remove incoming value from original preheader. PN->removeIncomingValue(A_Preheader); // Add incoming value from A_ExitingBlock. if (PN == B_IndVar) PN->addIncoming(BSV, A_ExitingBlock); else { PHINode *OrigPN = cast<PHINode>(InverseMap[PN]); Value *V2 = NULL; // If loop header is also loop exiting block then // OrigPN is incoming value for B loop header. if (A_ExitingBlock == ALoop->getHeader()) V2 = OrigPN; else V2 = OrigPN->getIncomingValueForBlock(A_ExitingBlock); PN->addIncoming(V2, A_ExitingBlock); } } else break; } DT->changeImmediateDominator(B_Header, A_ExitingBlock); DF->changeImmediateDominator(B_Header, A_ExitingBlock, DT); // [*] Update BLoop's exit block. Its new predecessor is BLoop's exit // block. Remove incoming PHINode values from ALoop's exiting block. // Add new incoming values from BLoop's incoming exiting value. // Update BLoop exit block's dominator info.. BasicBlock *B_ExitingBlock = cast<BasicBlock>(ValueMap[A_ExitingBlock]); for (BasicBlock::iterator BI = B_ExitBlock->begin(), BE = B_ExitBlock->end(); BI != BE; ++BI) { if (PHINode *PN = dyn_cast<PHINode>(BI)) { PN->addIncoming(ValueMap[PN->getIncomingValueForBlock(A_ExitingBlock)], B_ExitingBlock); PN->removeIncomingValue(A_ExitingBlock); } else break; } DT->changeImmediateDominator(B_ExitBlock, B_ExitingBlock); DF->changeImmediateDominator(B_ExitBlock, B_ExitingBlock, DT); //[*] Split ALoop's exit edge. This creates a new block which // serves two purposes. First one is to hold PHINode defnitions // to ensure that ALoop's LCSSA form. Second use it to act // as a preheader for BLoop. BasicBlock *A_ExitBlock = SplitEdge(A_ExitingBlock, B_Header, this); //[*] Preserve ALoop's LCSSA form. Create new forwarding PHINodes // in A_ExitBlock to redefine outgoing PHI definitions from ALoop. for(BasicBlock::iterator BI = B_Header->begin(), BE = B_Header->end(); BI != BE; ++BI) { if (PHINode *PN = dyn_cast<PHINode>(BI)) { Value *V1 = PN->getIncomingValueForBlock(A_ExitBlock); PHINode *newPHI = PHINode::Create(PN->getType(), PN->getName()); newPHI->addIncoming(V1, A_ExitingBlock); A_ExitBlock->getInstList().push_front(newPHI); PN->removeIncomingValue(A_ExitBlock); PN->addIncoming(newPHI, A_ExitBlock); } else break; } //[*] Eliminate split condition's inactive branch from ALoop. BasicBlock *A_SplitCondBlock = SplitCondition->getParent(); BranchInst *A_BR = cast<BranchInst>(A_SplitCondBlock->getTerminator()); BasicBlock *A_InactiveBranch = NULL; BasicBlock *A_ActiveBranch = NULL; A_ActiveBranch = A_BR->getSuccessor(0); A_InactiveBranch = A_BR->getSuccessor(1); A_BR->setUnconditionalDest(A_ActiveBranch); removeBlocks(A_InactiveBranch, L, A_ActiveBranch); //[*] Eliminate split condition's inactive branch in from BLoop. BasicBlock *B_SplitCondBlock = cast<BasicBlock>(ValueMap[A_SplitCondBlock]); BranchInst *B_BR = cast<BranchInst>(B_SplitCondBlock->getTerminator()); BasicBlock *B_InactiveBranch = NULL; BasicBlock *B_ActiveBranch = NULL; B_ActiveBranch = B_BR->getSuccessor(1); B_InactiveBranch = B_BR->getSuccessor(0); B_BR->setUnconditionalDest(B_ActiveBranch); removeBlocks(B_InactiveBranch, BLoop, B_ActiveBranch); BasicBlock *A_Header = ALoop->getHeader(); if (A_ExitingBlock == A_Header) return true; //[*] Move exit condition into split condition block to avoid // executing dead loop iteration. ICmpInst *B_ExitCondition = cast<ICmpInst>(ValueMap[ExitCondition]); Instruction *B_IndVarIncrement = cast<Instruction>(ValueMap[IVIncrement]); ICmpInst *B_SplitCondition = cast<ICmpInst>(ValueMap[SplitCondition]); moveExitCondition(A_SplitCondBlock, A_ActiveBranch, A_ExitBlock, ExitCondition, cast<ICmpInst>(SplitCondition), IndVar, IVIncrement, ALoop, EVOpNum); moveExitCondition(B_SplitCondBlock, B_ActiveBranch, B_ExitBlock, B_ExitCondition, B_SplitCondition, B_IndVar, B_IndVarIncrement, BLoop, EVOpNum); NumIndexSplit++; return true; }
/// updateLoopIterationSpace -- Update loop's iteration space if loop /// body is executed for certain IV range only. For example, /// /// for (i = 0; i < N; ++i) { /// if ( i > A && i < B) { /// ... /// } /// } /// is transformed to iterators from A to B, if A > 0 and B < N. /// bool LoopIndexSplit::updateLoopIterationSpace() { SplitCondition = NULL; if (ExitCondition->getPredicate() == ICmpInst::ICMP_NE || ExitCondition->getPredicate() == ICmpInst::ICMP_EQ) return false; BasicBlock *Latch = L->getLoopLatch(); BasicBlock *Header = L->getHeader(); BranchInst *BR = dyn_cast<BranchInst>(Header->getTerminator()); if (!BR) return false; if (!isa<BranchInst>(Latch->getTerminator())) return false; if (BR->isUnconditional()) return false; BinaryOperator *AND = dyn_cast<BinaryOperator>(BR->getCondition()); if (!AND) return false; if (AND->getOpcode() != Instruction::And) return false; ICmpInst *Op0 = dyn_cast<ICmpInst>(AND->getOperand(0)); ICmpInst *Op1 = dyn_cast<ICmpInst>(AND->getOperand(1)); if (!Op0 || !Op1) return false; IVBasedValues.insert(AND); IVBasedValues.insert(Op0); IVBasedValues.insert(Op1); if (!cleanBlock(Header)) return false; BasicBlock *ExitingBlock = ExitCondition->getParent(); if (!cleanBlock(ExitingBlock)) return false; // If the merge point for BR is not loop latch then skip this loop. if (BR->getSuccessor(0) != Latch) { DominanceFrontier::iterator DF0 = DF->find(BR->getSuccessor(0)); assert (DF0 != DF->end() && "Unable to find dominance frontier"); if (!DF0->second.count(Latch)) return false; } if (BR->getSuccessor(1) != Latch) { DominanceFrontier::iterator DF1 = DF->find(BR->getSuccessor(1)); assert (DF1 != DF->end() && "Unable to find dominance frontier"); if (!DF1->second.count(Latch)) return false; } // Verify that loop exiting block has only two predecessor, where one pred // is split condition block. The other predecessor will become exiting block's // dominator after CFG is updated. TODO : Handle CFG's where exiting block has // more then two predecessors. This requires extra work in updating dominator // information. BasicBlock *ExitingBBPred = NULL; for (pred_iterator PI = pred_begin(ExitingBlock), PE = pred_end(ExitingBlock); PI != PE; ++PI) { BasicBlock *BB = *PI; if (Header == BB) continue; if (ExitingBBPred) return false; else ExitingBBPred = BB; } if (!restrictLoopBound(*Op0)) return false; if (!restrictLoopBound(*Op1)) return false; // Update CFG. if (BR->getSuccessor(0) == ExitingBlock) BR->setUnconditionalDest(BR->getSuccessor(1)); else BR->setUnconditionalDest(BR->getSuccessor(0)); AND->eraseFromParent(); if (Op0->use_empty()) Op0->eraseFromParent(); if (Op1->use_empty()) Op1->eraseFromParent(); // Update domiantor info. Now, ExitingBlock has only one predecessor, // ExitingBBPred, and it is ExitingBlock's immediate domiantor. DT->changeImmediateDominator(ExitingBlock, ExitingBBPred); BasicBlock *ExitBlock = ExitingBlock->getTerminator()->getSuccessor(1); if (L->contains(ExitBlock)) ExitBlock = ExitingBlock->getTerminator()->getSuccessor(0); // If ExitingBlock is a member of the loop basic blocks' DF list then // replace ExitingBlock with header and exit block in the DF list DominanceFrontier::iterator ExitingBlockDF = DF->find(ExitingBlock); for (Loop::block_iterator I = L->block_begin(), E = L->block_end(); I != E; ++I) { BasicBlock *BB = *I; if (BB == Header || BB == ExitingBlock) continue; DominanceFrontier::iterator BBDF = DF->find(BB); DominanceFrontier::DomSetType::iterator DomSetI = BBDF->second.begin(); DominanceFrontier::DomSetType::iterator DomSetE = BBDF->second.end(); while (DomSetI != DomSetE) { DominanceFrontier::DomSetType::iterator CurrentItr = DomSetI; ++DomSetI; BasicBlock *DFBB = *CurrentItr; if (DFBB == ExitingBlock) { BBDF->second.erase(DFBB); for (DominanceFrontier::DomSetType::iterator EBI = ExitingBlockDF->second.begin(), EBE = ExitingBlockDF->second.end(); EBI != EBE; ++EBI) BBDF->second.insert(*EBI); } } } NumRestrictBounds++; return true; }
/// processOneIterationLoop -- Eliminate loop if loop body is executed /// only once. For example, /// for (i = 0; i < N; ++i) { /// if ( i == X) { /// ... /// } /// } /// bool LoopIndexSplit::processOneIterationLoop() { SplitCondition = NULL; BasicBlock *Latch = L->getLoopLatch(); BasicBlock *Header = L->getHeader(); BranchInst *BR = dyn_cast<BranchInst>(Header->getTerminator()); if (!BR) return false; if (!isa<BranchInst>(Latch->getTerminator())) return false; if (BR->isUnconditional()) return false; SplitCondition = dyn_cast<ICmpInst>(BR->getCondition()); if (!SplitCondition) return false; if (SplitCondition == ExitCondition) return false; if (SplitCondition->getPredicate() != ICmpInst::ICMP_EQ) return false; if (BR->getOperand(1) != Latch) return false; if (!IVBasedValues.count(SplitCondition->getOperand(0)) && !IVBasedValues.count(SplitCondition->getOperand(1))) return false; // If IV is used outside the loop then this loop traversal is required. // FIXME: Calculate and use last IV value. if (isUsedOutsideLoop(IVIncrement, L)) return false; // If BR operands are not IV or not loop invariants then skip this loop. Value *OPV = SplitCondition->getOperand(0); Value *SplitValue = SplitCondition->getOperand(1); if (!L->isLoopInvariant(SplitValue)) std::swap(OPV, SplitValue); if (!L->isLoopInvariant(SplitValue)) return false; Instruction *OPI = dyn_cast<Instruction>(OPV); if (!OPI) return false; if (OPI->getParent() != Header || isUsedOutsideLoop(OPI, L)) return false; Value *StartValue = IVStartValue; Value *ExitValue = IVExitValue;; if (OPV != IndVar) { // If BR operand is IV based then use this operand to calculate // effective conditions for loop body. BinaryOperator *BOPV = dyn_cast<BinaryOperator>(OPV); if (!BOPV) return false; if (BOPV->getOpcode() != Instruction::Add) return false; StartValue = BinaryOperator::CreateAdd(OPV, StartValue, "" , BR); ExitValue = BinaryOperator::CreateAdd(OPV, ExitValue, "" , BR); } if (!cleanBlock(Header)) return false; if (!cleanBlock(Latch)) return false; // If the merge point for BR is not loop latch then skip this loop. if (BR->getSuccessor(0) != Latch) { DominanceFrontier::iterator DF0 = DF->find(BR->getSuccessor(0)); assert (DF0 != DF->end() && "Unable to find dominance frontier"); if (!DF0->second.count(Latch)) return false; } if (BR->getSuccessor(1) != Latch) { DominanceFrontier::iterator DF1 = DF->find(BR->getSuccessor(1)); assert (DF1 != DF->end() && "Unable to find dominance frontier"); if (!DF1->second.count(Latch)) return false; } // Now, Current loop L contains compare instruction // that compares induction variable, IndVar, against loop invariant. And // entire (i.e. meaningful) loop body is dominated by this compare // instruction. In such case eliminate // loop structure surrounding this loop body. For example, // for (int i = start; i < end; ++i) { // if ( i == somevalue) { // loop_body // } // } // can be transformed into // if (somevalue >= start && somevalue < end) { // i = somevalue; // loop_body // } // Replace index variable with split value in loop body. Loop body is executed // only when index variable is equal to split value. IndVar->replaceAllUsesWith(SplitValue); // Replace split condition in header. // Transform // SplitCondition : icmp eq i32 IndVar, SplitValue // into // c1 = icmp uge i32 SplitValue, StartValue // c2 = icmp ult i32 SplitValue, ExitValue // and i32 c1, c2 Instruction *C1 = new ICmpInst(BR, ExitCondition->isSigned() ? ICmpInst::ICMP_SGE : ICmpInst::ICMP_UGE, SplitValue, StartValue, "lisplit"); CmpInst::Predicate C2P = ExitCondition->getPredicate(); BranchInst *LatchBR = cast<BranchInst>(Latch->getTerminator()); if (LatchBR->getOperand(1) != Header) C2P = CmpInst::getInversePredicate(C2P); Instruction *C2 = new ICmpInst(BR, C2P, SplitValue, ExitValue, "lisplit"); Instruction *NSplitCond = BinaryOperator::CreateAnd(C1, C2, "lisplit", BR); SplitCondition->replaceAllUsesWith(NSplitCond); SplitCondition->eraseFromParent(); // Remove Latch to Header edge. BasicBlock *LatchSucc = NULL; Header->removePredecessor(Latch); for (succ_iterator SI = succ_begin(Latch), E = succ_end(Latch); SI != E; ++SI) { if (Header != *SI) LatchSucc = *SI; } // Clean up latch block. Value *LatchBRCond = LatchBR->getCondition(); LatchBR->setUnconditionalDest(LatchSucc); RecursivelyDeleteTriviallyDeadInstructions(LatchBRCond); LPM->deleteLoopFromQueue(L); // Update Dominator Info. // Only CFG change done is to remove Latch to Header edge. This // does not change dominator tree because Latch did not dominate // Header. if (DF) { DominanceFrontier::iterator HeaderDF = DF->find(Header); if (HeaderDF != DF->end()) DF->removeFromFrontier(HeaderDF, Header); DominanceFrontier::iterator LatchDF = DF->find(Latch); if (LatchDF != DF->end()) DF->removeFromFrontier(LatchDF, Header); } ++NumIndexSplitRemoved; return true; }
// Index split Loop L. Return true if loop is split. bool LoopIndexSplit::runOnLoop(Loop *IncomingLoop, LPPassManager &LPM_Ref) { L = IncomingLoop; LPM = &LPM_Ref; // If LoopSimplify form is not available, stay out of trouble. if (!L->isLoopSimplifyForm()) return false; // FIXME - Nested loops make dominator info updates tricky. if (!L->getSubLoops().empty()) return false; DT = &getAnalysis<DominatorTree>(); LI = &getAnalysis<LoopInfo>(); DF = &getAnalysis<DominanceFrontier>(); // Initialize loop data. IndVar = L->getCanonicalInductionVariable(); if (!IndVar) return false; bool P1InLoop = L->contains(IndVar->getIncomingBlock(1)); IVStartValue = IndVar->getIncomingValue(!P1InLoop); IVIncrement = dyn_cast<Instruction>(IndVar->getIncomingValue(P1InLoop)); if (!IVIncrement) return false; IVBasedValues.clear(); IVBasedValues.insert(IndVar); IVBasedValues.insert(IVIncrement); for (Loop::block_iterator I = L->block_begin(), E = L->block_end(); I != E; ++I) for(BasicBlock::iterator BI = (*I)->begin(), BE = (*I)->end(); BI != BE; ++BI) { if (BinaryOperator *BO = dyn_cast<BinaryOperator>(BI)) if (BO != IVIncrement && (BO->getOpcode() == Instruction::Add || BO->getOpcode() == Instruction::Sub)) if (IVBasedValues.count(BO->getOperand(0)) && L->isLoopInvariant(BO->getOperand(1))) IVBasedValues.insert(BO); } // Reject loop if loop exit condition is not suitable. BasicBlock *ExitingBlock = L->getExitingBlock(); if (!ExitingBlock) return false; BranchInst *EBR = dyn_cast<BranchInst>(ExitingBlock->getTerminator()); if (!EBR) return false; ExitCondition = dyn_cast<ICmpInst>(EBR->getCondition()); if (!ExitCondition) return false; if (ExitingBlock != L->getLoopLatch()) return false; IVExitValue = ExitCondition->getOperand(1); if (!L->isLoopInvariant(IVExitValue)) IVExitValue = ExitCondition->getOperand(0); if (!L->isLoopInvariant(IVExitValue)) return false; if (!IVBasedValues.count( ExitCondition->getOperand(IVExitValue == ExitCondition->getOperand(0)))) return false; // If start value is more then exit value where induction variable // increments by 1 then we are potentially dealing with an infinite loop. // Do not index split this loop. if (ConstantInt *SV = dyn_cast<ConstantInt>(IVStartValue)) if (ConstantInt *EV = dyn_cast<ConstantInt>(IVExitValue)) if (SV->getSExtValue() > EV->getSExtValue()) return false; if (processOneIterationLoop()) return true; if (updateLoopIterationSpace()) return true; if (splitLoop()) return true; return false; }
bool RangedAddressSanitizer::runOnFunction(Function &F) { if (getenv("FASAN_DISABLE")) { SPM_DEBUG( dbgs() << "FASan : disabled\n" ); return false; } DL_ = &getAnalysis<DataLayout>(); DT_ = &getAnalysis<DominatorTree>(); LI_ = &getAnalysis<LoopInfo>(); RI_ = &getAnalysis<ReduceIndexation>(); #ifdef ENABLE_REUSE RE_ = &getAnalysis<RelativeExecutions>(); #endif RMM_ = &getAnalysis<RelativeMinMax>(); Module_ = F.getParent(); Context_ = &Module_->getContext(); Type *VoidTy = Type::getVoidTy(*Context_); IntegerType *IntTy = IntegerType::getInt64Ty(*Context_); IntegerType *BoolTy = IntegerType::getInt1Ty(*Context_); PointerType *IntPtrTy = PointerType::getUnqual(IntTy); PointerType *VoidPtrTy = PointerType::getInt8PtrTy(*Context_); SPM_DEBUG( F.dump() ); outs() << "[IterationInfo]\n"; for (Loop * loop : *LI_) { ii_visitLoop(loop); } outs() << "[EndOfIterationInfo]\n"; #if 0 // disabled initialization,shutdown sequence for FASan if (F.getName() == "main") { SPM_DEBUG(dbgs() << "RangedAddressSanitizer: inserting hwloc calls into " "main function\n"); FunctionType *FnType = FunctionType::get(VoidTy, ArrayRef<Type*>(), false); IRBuilder<> IRB(&(*F.getEntryBlock().begin())); Constant *Init = Module_->getOrInsertFunction("__spm_init", FnType); IRB.CreateCall(Init); Constant *End = Module_->getOrInsertFunction("__spm_end", FnType); for (auto &BB : F) { TerminatorInst *TI = BB.getTerminator(); if (isa<ReturnInst>(TI)) { IRB.SetInsertPoint(TI); IRB.CreateCall(End); } } } #endif if (!ClFunc.empty() && F.getName() != ClFunc) { SPM_DEBUG(dbgs() << "RangedAddressSanitizer: skipping function " << F.getName() << "\n"); return false; } Calls_.clear(); SPM_DEBUG(dbgs() << "RangedAddressSanitizer: processing function " << F.getName() << "\n"); std::vector<Type*> ReuseFnFormals = { VoidPtrTy, IntTy, IntTy, IntTy }; FunctionType *ReuseFnType = FunctionType::get(BoolTy, ReuseFnFormals, false); ReuseFn_ = F.getParent()->getOrInsertFunction("__fasan_check", ReuseFnType); ReuseFnDestroy_ = F.getParent()->getOrInsertFunction("__spm_give", ReuseFnType); // Visit all loops in bottom-up order (innter-most loops first) std::set<BasicBlock*> Processed; auto Entry = DT_->getRootNode(); for (auto ET = po_begin(Entry), EE = po_end(Entry); ET != EE; ++ET) { BasicBlock *Header = (*ET)->getBlock(); if (LI_->isLoopHeader(Header)) { SPM_DEBUG(dbgs() << "RangedAddressSanitizer: processing loop at " << Header->getName() << "\n"); Loop *L = LI_->getLoopFor(Header); if (L->getNumBackEdges() != 1 || std::distance(pred_begin(Header), pred_end(Header)) != 2) { SPM_DEBUG(dbgs() << "RangedAddressSanitizer: loop has multiple " << "backedges or multiple incoming outer blocks\n"); continue; } SPM_DEBUG(dbgs() << "RangedAddressSanitizer: processing loop at " << Header->getName() << "\n"); // visit all memory acccesses in this loop for (auto BB = L->block_begin(), BE = L->block_end(); BB != BE; ++BB) { if (!Processed.count(*BB)) { Processed.insert(*BB); for (auto &I : *(*BB)) generateCallFor(L, &I); } } } } // FAsan logic goes here std::map<const BasicBlock*,BasicBlock*> clonedBlockMap; // keeps track of cloned regions to avoid redundant cloning std::vector<CallInst*> ToInline; for (auto &CI : Calls_) { BasicBlock * Preheader = CI.Preheader; // TODO decide whether it is worthwhile to optimize for this case // insert range check IRBuilder<> IRB(Preheader->getTerminator()); Value *VoidArray = IRB.CreateBitCast(CI.Array, VoidPtrTy); std::vector<Value*> Args = { VoidArray, CI.Min, CI.Max, CI.Reuse }; CallInst *CR = IRB.CreateCall(ReuseFn_, Args); ToInline.push_back(CR); // verify if this loop was already instrumented TerminatorInst * preHeaderTerm = CR->getParent()->getTerminator(); BranchInst * preHeaderBranch = dyn_cast<BranchInst>(preHeaderTerm); if (preHeaderBranch && preHeaderBranch->isConditional()) { // discover the structure of the instrumented code (safe and default region) // abort, if this does not look like instrumented code BasicBlock * firstTarget = preHeaderBranch->getSuccessor(0); BasicBlock * secondTarget = preHeaderBranch->getSuccessor(1); BasicBlock * safeHeader, * defHeader; if (clonedBlockMap.count(firstTarget)) { defHeader = firstTarget; safeHeader = clonedBlockMap[firstTarget]; assert(safeHeader == secondTarget); } else { assert(clonedBlockMap.count(secondTarget)); defHeader = secondTarget; safeHeader = clonedBlockMap[secondTarget]; assert(safeHeader == firstTarget); } SPM_DEBUG( dbgs() << "FASan: (Unsupported) second array in safe region controlled by " << * preHeaderBranch << "\n" ); Loop * defLoop = LI_->getLoopFor(defHeader); assert(defLoop && "default region is not a loop!"); Loop::block_iterator itBodyBlock,S,E; S = defLoop->block_begin(); E = defLoop->block_end(); // mark accesses in cloned region as safe for (itBodyBlock = S;itBodyBlock != E; ++itBodyBlock) { BasicBlock * defBodyBlock = *itBodyBlock; BasicBlock * safeBodyBlock = clonedBlockMap[defBodyBlock]; for(auto & inst : *safeBodyBlock) { markSafeArrayUse(&inst, CI.Array); } } // add conjunctive test Value * oldCond = preHeaderBranch->getCondition(); Value * joinedCond = IRB.CreateAnd(oldCond, CR, "allsafe"); preHeaderBranch->setCondition(joinedCond); } else { // get loop Loop* finalLoop = CI.FinalLoop; Loop::block_iterator itBodyBlock,S,E; S = finalLoop->block_begin(); E = finalLoop->block_end(); // clone loop body (cloned loop will run unchecked) ValueToValueMapTy cloneMap; BasicBlock * clonedHeader = 0; std::vector<BasicBlock*> clonedBlocks; for (itBodyBlock = S;itBodyBlock != E; ++itBodyBlock) { const BasicBlock * bodyBlock = *itBodyBlock; BasicBlock * clonedBlock = CloneBasicBlock(bodyBlock, cloneMap, "_checked", &F, 0); cloneMap[bodyBlock] = clonedBlock; clonedBlockMap[bodyBlock] = clonedBlock; clonedBlocks.push_back(clonedBlock); if (bodyBlock == finalLoop->getHeader()) { clonedHeader = clonedBlock; SPM_DEBUG( dbgs() << "FASan: loop header case at " << bodyBlock->getName() << "\n" ); } else { SPM_DEBUG( dbgs() << "FASan: non-header block at " << bodyBlock->getName() << "\n" ); } } if (!clonedHeader) { // TODO run clean-up code SPM_DEBUG( dbgs() << "FASan: could not find header!\n"); abort(); } // Remap uses inside cloned region (mark pointers in the region as unguarded) for (BasicBlock * block : clonedBlocks) { for(auto & inst : *block) { RemapInstruction(&inst, cloneMap, RF_IgnoreMissingEntries); markSafeArrayUse(&inst, CI.Array); } } // TODO fix PHI-nodes in exit blocks // Rewire terminator of the range check to branch to the cloned region TerminatorInst * checkTermInst = CR->getParent()->getTerminator(); if (BranchInst * checkBranchInst = dyn_cast<BranchInst>(checkTermInst)) { if (checkBranchInst->isUnconditional()) { BasicBlock * defTarget = checkBranchInst->getSuccessor(0); BranchInst * modifiedBranchInst = BranchInst::Create(clonedHeader, defTarget, CR, checkBranchInst); checkBranchInst->replaceAllUsesWith(modifiedBranchInst); checkBranchInst->eraseFromParent(); } else { SPM_DEBUG( dbgs() << "FASan: Unexpected conditional branch (preheader should branch unconditional, other array checks will introduce conditional branches) " << * checkTermInst << "\n" ); abort(); } } else { SPM_DEBUG( dbgs() << "FASan: unsupported terminator type " << * checkTermInst << "\n" ); abort(); } } #if 0 IRB.SetInsertPoint(&(*CI.Final->begin())); IRB.CreateCall(ReuseFnDestroy_, Args); #endif SPM_DEBUG(dbgs() << "RangedAddressSanitizer: call instruction: " << *CR << "\n"); } // inline calls #ifdef FASAN_INLINE_RUNTIME for (CallInst * call : ToInline) { assert(call); InlineFunctionInfo IFI; InlineFunction(call, IFI, false); } #endif SPM_DEBUG( F.dump() ); return true; }
/// \brief Simplify one loop and queue further loops for simplification. /// /// FIXME: Currently this accepts both lots of analyses that it uses and a raw /// Pass pointer. The Pass pointer is used by numerous utilities to update /// specific analyses. Rather than a pass it would be much cleaner and more /// explicit if they accepted the analysis directly and then updated it. static bool simplifyOneLoop(Loop *L, SmallVectorImpl<Loop *> &Worklist, DominatorTree *DT, LoopInfo *LI, ScalarEvolution *SE, Pass *PP, AssumptionCache *AC) { bool Changed = false; ReprocessLoop: // Check to see that no blocks (other than the header) in this loop have // predecessors that are not in the loop. This is not valid for natural // loops, but can occur if the blocks are unreachable. Since they are // unreachable we can just shamelessly delete those CFG edges! for (Loop::block_iterator BB = L->block_begin(), E = L->block_end(); BB != E; ++BB) { if (*BB == L->getHeader()) continue; SmallPtrSet<BasicBlock*, 4> BadPreds; for (pred_iterator PI = pred_begin(*BB), PE = pred_end(*BB); PI != PE; ++PI) { BasicBlock *P = *PI; if (!L->contains(P)) BadPreds.insert(P); } // Delete each unique out-of-loop (and thus dead) predecessor. for (BasicBlock *P : BadPreds) { DEBUG(dbgs() << "LoopSimplify: Deleting edge from dead predecessor " << P->getName() << "\n"); // Inform each successor of each dead pred. for (succ_iterator SI = succ_begin(P), SE = succ_end(P); SI != SE; ++SI) (*SI)->removePredecessor(P); // Zap the dead pred's terminator and replace it with unreachable. TerminatorInst *TI = P->getTerminator(); TI->replaceAllUsesWith(UndefValue::get(TI->getType())); P->getTerminator()->eraseFromParent(); new UnreachableInst(P->getContext(), P); Changed = true; } } // If there are exiting blocks with branches on undef, resolve the undef in // the direction which will exit the loop. This will help simplify loop // trip count computations. SmallVector<BasicBlock*, 8> ExitingBlocks; L->getExitingBlocks(ExitingBlocks); for (SmallVectorImpl<BasicBlock *>::iterator I = ExitingBlocks.begin(), E = ExitingBlocks.end(); I != E; ++I) if (BranchInst *BI = dyn_cast<BranchInst>((*I)->getTerminator())) if (BI->isConditional()) { if (UndefValue *Cond = dyn_cast<UndefValue>(BI->getCondition())) { DEBUG(dbgs() << "LoopSimplify: Resolving \"br i1 undef\" to exit in " << (*I)->getName() << "\n"); BI->setCondition(ConstantInt::get(Cond->getType(), !L->contains(BI->getSuccessor(0)))); // This may make the loop analyzable, force SCEV recomputation. if (SE) SE->forgetLoop(L); Changed = true; } } // Does the loop already have a preheader? If so, don't insert one. BasicBlock *Preheader = L->getLoopPreheader(); if (!Preheader) { Preheader = InsertPreheaderForLoop(L, PP); if (Preheader) { ++NumInserted; Changed = true; } } // Next, check to make sure that all exit nodes of the loop only have // predecessors that are inside of the loop. This check guarantees that the // loop preheader/header will dominate the exit blocks. If the exit block has // predecessors from outside of the loop, split the edge now. SmallVector<BasicBlock*, 8> ExitBlocks; L->getExitBlocks(ExitBlocks); SmallSetVector<BasicBlock *, 8> ExitBlockSet(ExitBlocks.begin(), ExitBlocks.end()); for (SmallSetVector<BasicBlock *, 8>::iterator I = ExitBlockSet.begin(), E = ExitBlockSet.end(); I != E; ++I) { BasicBlock *ExitBlock = *I; for (pred_iterator PI = pred_begin(ExitBlock), PE = pred_end(ExitBlock); PI != PE; ++PI) // Must be exactly this loop: no subloops, parent loops, or non-loop preds // allowed. if (!L->contains(*PI)) { if (rewriteLoopExitBlock(L, ExitBlock, DT, LI, PP)) { ++NumInserted; Changed = true; } break; } } // If the header has more than two predecessors at this point (from the // preheader and from multiple backedges), we must adjust the loop. BasicBlock *LoopLatch = L->getLoopLatch(); if (!LoopLatch) { // If this is really a nested loop, rip it out into a child loop. Don't do // this for loops with a giant number of backedges, just factor them into a // common backedge instead. if (L->getNumBackEdges() < 8) { if (Loop *OuterL = separateNestedLoop(L, Preheader, DT, LI, SE, PP, AC)) { ++NumNested; // Enqueue the outer loop as it should be processed next in our // depth-first nest walk. Worklist.push_back(OuterL); // This is a big restructuring change, reprocess the whole loop. Changed = true; // GCC doesn't tail recursion eliminate this. // FIXME: It isn't clear we can't rely on LLVM to TRE this. goto ReprocessLoop; } } // If we either couldn't, or didn't want to, identify nesting of the loops, // insert a new block that all backedges target, then make it jump to the // loop header. LoopLatch = insertUniqueBackedgeBlock(L, Preheader, DT, LI); if (LoopLatch) { ++NumInserted; Changed = true; } } const DataLayout &DL = L->getHeader()->getModule()->getDataLayout(); // Scan over the PHI nodes in the loop header. Since they now have only two // incoming values (the loop is canonicalized), we may have simplified the PHI // down to 'X = phi [X, Y]', which should be replaced with 'Y'. PHINode *PN; for (BasicBlock::iterator I = L->getHeader()->begin(); (PN = dyn_cast<PHINode>(I++)); ) if (Value *V = SimplifyInstruction(PN, DL, nullptr, DT, AC)) { if (SE) SE->forgetValue(PN); PN->replaceAllUsesWith(V); PN->eraseFromParent(); } // If this loop has multiple exits and the exits all go to the same // block, attempt to merge the exits. This helps several passes, such // as LoopRotation, which do not support loops with multiple exits. // SimplifyCFG also does this (and this code uses the same utility // function), however this code is loop-aware, where SimplifyCFG is // not. That gives it the advantage of being able to hoist // loop-invariant instructions out of the way to open up more // opportunities, and the disadvantage of having the responsibility // to preserve dominator information. bool UniqueExit = true; if (!ExitBlocks.empty()) for (unsigned i = 1, e = ExitBlocks.size(); i != e; ++i) if (ExitBlocks[i] != ExitBlocks[0]) { UniqueExit = false; break; } if (UniqueExit) { for (unsigned i = 0, e = ExitingBlocks.size(); i != e; ++i) { BasicBlock *ExitingBlock = ExitingBlocks[i]; if (!ExitingBlock->getSinglePredecessor()) continue; BranchInst *BI = dyn_cast<BranchInst>(ExitingBlock->getTerminator()); if (!BI || !BI->isConditional()) continue; CmpInst *CI = dyn_cast<CmpInst>(BI->getCondition()); if (!CI || CI->getParent() != ExitingBlock) continue; // Attempt to hoist out all instructions except for the // comparison and the branch. bool AllInvariant = true; bool AnyInvariant = false; for (BasicBlock::iterator I = ExitingBlock->begin(); &*I != BI; ) { Instruction *Inst = I++; // Skip debug info intrinsics. if (isa<DbgInfoIntrinsic>(Inst)) continue; if (Inst == CI) continue; if (!L->makeLoopInvariant(Inst, AnyInvariant, Preheader ? Preheader->getTerminator() : nullptr)) { AllInvariant = false; break; } } if (AnyInvariant) { Changed = true; // The loop disposition of all SCEV expressions that depend on any // hoisted values have also changed. if (SE) SE->forgetLoopDispositions(L); } if (!AllInvariant) continue; // The block has now been cleared of all instructions except for // a comparison and a conditional branch. SimplifyCFG may be able // to fold it now. if (!FoldBranchToCommonDest(BI)) continue; // Success. The block is now dead, so remove it from the loop, // update the dominator tree and delete it. DEBUG(dbgs() << "LoopSimplify: Eliminating exiting block " << ExitingBlock->getName() << "\n"); // Notify ScalarEvolution before deleting this block. Currently assume the // parent loop doesn't change (spliting edges doesn't count). If blocks, // CFG edges, or other values in the parent loop change, then we need call // to forgetLoop() for the parent instead. if (SE) SE->forgetLoop(L); assert(pred_begin(ExitingBlock) == pred_end(ExitingBlock)); Changed = true; LI->removeBlock(ExitingBlock); DomTreeNode *Node = DT->getNode(ExitingBlock); const std::vector<DomTreeNodeBase<BasicBlock> *> &Children = Node->getChildren(); while (!Children.empty()) { DomTreeNode *Child = Children.front(); DT->changeImmediateDominator(Child, Node->getIDom()); } DT->eraseNode(ExitingBlock); BI->getSuccessor(0)->removePredecessor(ExitingBlock); BI->getSuccessor(1)->removePredecessor(ExitingBlock); ExitingBlock->eraseFromParent(); } } return Changed; }
/// GetIfCondition - Given a basic block (BB) with two predecessors, /// check to see if the merge at this block is due /// to an "if condition". If so, return the boolean condition that determines /// which entry into BB will be taken. Also, return by references the block /// that will be entered from if the condition is true, and the block that will /// be entered if the condition is false. /// /// This does no checking to see if the true/false blocks have large or unsavory /// instructions in them. Value *llvm::GetIfCondition(BasicBlock *BB, BasicBlock *&IfTrue, BasicBlock *&IfFalse) { PHINode *SomePHI = dyn_cast<PHINode>(BB->begin()); BasicBlock *Pred1 = NULL; BasicBlock *Pred2 = NULL; if (SomePHI) { if (SomePHI->getNumIncomingValues() != 2) return NULL; Pred1 = SomePHI->getIncomingBlock(0); Pred2 = SomePHI->getIncomingBlock(1); } else { pred_iterator PI = pred_begin(BB), PE = pred_end(BB); if (PI == PE) // No predecessor return NULL; Pred1 = *PI++; if (PI == PE) // Only one predecessor return NULL; Pred2 = *PI++; if (PI != PE) // More than two predecessors return NULL; } // We can only handle branches. Other control flow will be lowered to // branches if possible anyway. BranchInst *Pred1Br = dyn_cast<BranchInst>(Pred1->getTerminator()); BranchInst *Pred2Br = dyn_cast<BranchInst>(Pred2->getTerminator()); if (Pred1Br == 0 || Pred2Br == 0) return 0; // Eliminate code duplication by ensuring that Pred1Br is conditional if // either are. if (Pred2Br->isConditional()) { // If both branches are conditional, we don't have an "if statement". In // reality, we could transform this case, but since the condition will be // required anyway, we stand no chance of eliminating it, so the xform is // probably not profitable. if (Pred1Br->isConditional()) return 0; std::swap(Pred1, Pred2); std::swap(Pred1Br, Pred2Br); } if (Pred1Br->isConditional()) { // The only thing we have to watch out for here is to make sure that Pred2 // doesn't have incoming edges from other blocks. If it does, the condition // doesn't dominate BB. if (Pred2->getSinglePredecessor() == 0) return 0; // If we found a conditional branch predecessor, make sure that it branches // to BB and Pred2Br. If it doesn't, this isn't an "if statement". if (Pred1Br->getSuccessor(0) == BB && Pred1Br->getSuccessor(1) == Pred2) { IfTrue = Pred1; IfFalse = Pred2; } else if (Pred1Br->getSuccessor(0) == Pred2 && Pred1Br->getSuccessor(1) == BB) { IfTrue = Pred2; IfFalse = Pred1; } else { // We know that one arm of the conditional goes to BB, so the other must // go somewhere unrelated, and this must not be an "if statement". return 0; } return Pred1Br->getCondition(); } // Ok, if we got here, both predecessors end with an unconditional branch to // BB. Don't panic! If both blocks only have a single (identical) // predecessor, and THAT is a conditional branch, then we're all ok! BasicBlock *CommonPred = Pred1->getSinglePredecessor(); if (CommonPred == 0 || CommonPred != Pred2->getSinglePredecessor()) return 0; // Otherwise, if this is a conditional branch, then we can use it! BranchInst *BI = dyn_cast<BranchInst>(CommonPred->getTerminator()); if (BI == 0) return 0; assert(BI->isConditional() && "Two successors but not conditional?"); if (BI->getSuccessor(0) == Pred1) { IfTrue = Pred1; IfFalse = Pred2; } else { IfTrue = Pred2; IfFalse = Pred1; } return BI->getCondition(); }
void CPFlowFunction::visitBranchInst(BranchInst &BI) { CPLatticePoint* result = new CPLatticePoint(*(info_in_casted.back())); info_in_casted.pop_back(); BranchInst* current = &BI; if (BI.isConditional()) { Value* cond = BI.getCondition(); if (isa<ICmpInst>(cond)) { std::pair<Use*, Use *> branches = helper::getOps(BI); Use* true_branch = branches.first; Use* false_branch = branches.second; ICmpInst* cmp = dyn_cast<ICmpInst>(cond); std::pair<Use*, Use *> operands = helper::getOps(*cmp); Use* rhs = operands.second; Use* lhs = operands.first; ConstantInt* rhs_const = NULL; ConstantInt* lhs_const = NULL; // get the rhs/lhs as a constant int if (isa<ConstantInt>(rhs)) { rhs_const = dyn_cast<ConstantInt>(rhs); } else if (result->representation.count(rhs->get()) > 0) { rhs_const = result->representation[rhs->get()]; } else { rhs_const = ConstantInt::get(context, llvm::APInt(32, 0, true)); } if (isa<ConstantInt>(lhs)) { lhs_const = dyn_cast<ConstantInt>(lhs->get()); } else if (result->representation.count(lhs->get()) > 0) { lhs_const = result->representation[lhs->get()]; } else { lhs_const = ConstantInt::get(context, llvm::APInt(32, 0, true)); } // Create successors CPLatticePoint* true_branchCLP = new CPLatticePoint(false, false, std::map<Value*,ConstantInt*>(result->representation)); CPLatticePoint* false_branchCLP = new CPLatticePoint(false, false, std::map<Value*,ConstantInt*>(result->representation)); // get the predicate int predicate = 0; predicate = cmp->isSigned() ? cmp->getSignedPredicate() : cmp->getUnsignedPredicate(); if (predicate == CmpInst::ICMP_EQ) { if (isa<ConstantInt>(lhs)) { true_branchCLP->representation[rhs->get()] = lhs_const; } else if (isa<ConstantInt>(rhs)) { true_branchCLP->representation[lhs->get()] = rhs_const; } out_map[true_branch->get()] = true_branchCLP; out_map[false_branch->get()] = false_branchCLP; } else if (predicate == CmpInst::ICMP_NE) { if (isa<ConstantInt>(lhs)) { false_branchCLP->representation[rhs->get()] = lhs_const; } else if (isa<ConstantInt>(rhs)) { false_branchCLP->representation[lhs->get()] = rhs_const; } out_map[true_branch->get()] = true_branchCLP; out_map[false_branch->get()] = false_branchCLP; } else { for (std::map<Value *, LatticePoint *>::iterator it=out_map.begin(); it != out_map.end(); ++it){ Value* elm = it->first; out_map[elm] = new CPLatticePoint(*result); } } } else { for (std::map<Value *, LatticePoint *>::iterator it=out_map.begin(); it != out_map.end(); ++it){ Value* elm = it->first; out_map[elm] = new CPLatticePoint(*result); } } } else { for (std::map<Value *, LatticePoint *>::iterator it=out_map.begin(); it != out_map.end(); ++it){ Value* elm = it->first; out_map[elm] = new CPLatticePoint(*result); } } }