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; }
bool AMDGPUCodeGenPrepare::promoteUniformOpToI32(ICmpInst &I) const { assert(needsPromotionToI32(I.getOperand(0)->getType()) && "I does not need promotion to i32"); IRBuilder<> Builder(&I); Builder.SetCurrentDebugLocation(I.getDebugLoc()); Type *I32Ty = getI32Ty(Builder, I.getOperand(0)->getType()); Value *ExtOp0 = nullptr; Value *ExtOp1 = nullptr; Value *NewICmp = nullptr; if (I.isSigned()) { ExtOp0 = Builder.CreateSExt(I.getOperand(0), I32Ty); ExtOp1 = Builder.CreateSExt(I.getOperand(1), I32Ty); } else { ExtOp0 = Builder.CreateZExt(I.getOperand(0), I32Ty); ExtOp1 = Builder.CreateZExt(I.getOperand(1), I32Ty); } NewICmp = Builder.CreateICmp(I.getPredicate(), ExtOp0, ExtOp1); I.replaceAllUsesWith(NewICmp); I.eraseFromParent(); 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; }
void IndVarSimplify::EliminateIVComparisons() { // Look for ICmp users. for (IVUsers::iterator I = IU->begin(), E = IU->end(); I != E; ++I) { IVStrideUse &UI = *I; ICmpInst *ICmp = dyn_cast<ICmpInst>(UI.getUser()); if (!ICmp) continue; bool Swapped = UI.getOperandValToReplace() == ICmp->getOperand(1); ICmpInst::Predicate Pred = ICmp->getPredicate(); if (Swapped) Pred = ICmpInst::getSwappedPredicate(Pred); // Get the SCEVs for the ICmp operands. const SCEV *S = IU->getReplacementExpr(UI); const SCEV *X = SE->getSCEV(ICmp->getOperand(!Swapped)); // Simplify unnecessary loops away. const Loop *ICmpLoop = LI->getLoopFor(ICmp->getParent()); S = SE->getSCEVAtScope(S, ICmpLoop); X = SE->getSCEVAtScope(X, ICmpLoop); // If the condition is always true or always false, replace it with // a constant value. if (SE->isKnownPredicate(Pred, S, X)) ICmp->replaceAllUsesWith(ConstantInt::getTrue(ICmp->getContext())); else if (SE->isKnownPredicate(ICmpInst::getInversePredicate(Pred), S, X)) ICmp->replaceAllUsesWith(ConstantInt::getFalse(ICmp->getContext())); else continue; DEBUG(dbgs() << "INDVARS: Eliminated comparison: " << *ICmp << '\n'); DeadInsts.push_back(ICmp); } }
bool visitICmpInst(ICmpInst& inst) { // errs() << "got icmp instruction! " << inst << '\n'; bool changed = false; if (inst.getPredicate() == CmpInst::ICMP_EQ) { assert(inst.getNumOperands() == 2); if (inst.getOperand(1) == processing) { inst.swapOperands(); changed = true; any_changes = true; } assert(dyn_cast<Instruction>(inst.getOperand(0)) == processing); Value* other = inst.getOperand(1); if (isa<ConstantPointerNull>(other)) { if (VERBOSITY("opt") >= 2) { errs() << inst << '\n'; errs() << "replacing with false!\n"; } Value* new_value = ConstantInt::getFalse(other->getContext()); inst.replaceAllUsesWith(new_value); inst.eraseFromParent(); changed = true; any_changes = true; } } return changed; }
/// MatchSelectPattern - Pattern match integer [SU]MIN, [SU]MAX, and ABS idioms, /// returning the kind and providing the out parameter results if we /// successfully match. static SelectPatternFlavor MatchSelectPattern(Value *V, Value *&LHS, Value *&RHS) { SelectInst *SI = dyn_cast<SelectInst>(V); if (SI == 0) return SPF_UNKNOWN; ICmpInst *ICI = dyn_cast<ICmpInst>(SI->getCondition()); if (ICI == 0) return SPF_UNKNOWN; LHS = ICI->getOperand(0); RHS = ICI->getOperand(1); // (icmp X, Y) ? X : Y if (SI->getTrueValue() == ICI->getOperand(0) && SI->getFalseValue() == ICI->getOperand(1)) { switch (ICI->getPredicate()) { default: return SPF_UNKNOWN; // Equality. case ICmpInst::ICMP_UGT: case ICmpInst::ICMP_UGE: return SPF_UMAX; case ICmpInst::ICMP_SGT: case ICmpInst::ICMP_SGE: return SPF_SMAX; case ICmpInst::ICMP_ULT: case ICmpInst::ICMP_ULE: return SPF_UMIN; case ICmpInst::ICMP_SLT: case ICmpInst::ICMP_SLE: return SPF_SMIN; } } // (icmp X, Y) ? Y : X if (SI->getTrueValue() == ICI->getOperand(1) && SI->getFalseValue() == ICI->getOperand(0)) { switch (ICI->getPredicate()) { default: return SPF_UNKNOWN; // Equality. case ICmpInst::ICMP_UGT: case ICmpInst::ICMP_UGE: return SPF_UMIN; case ICmpInst::ICMP_SGT: case ICmpInst::ICMP_SGE: return SPF_SMIN; case ICmpInst::ICMP_ULT: case ICmpInst::ICMP_ULE: return SPF_UMAX; case ICmpInst::ICMP_SLT: case ICmpInst::ICMP_SLE: return SPF_SMAX; } } // TODO: (X > 4) ? X : 5 --> (X >= 5) ? X : 5 --> MAX(X, 5) return SPF_UNKNOWN; }
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 LowerExpectIntrinsic::HandleIfExpect(BranchInst *BI) { if (BI->isUnconditional()) return false; // Handle non-optimized IR code like: // %expval = call i64 @llvm.expect.i64(i64 %conv1, i64 1) // %tobool = icmp ne i64 %expval, 0 // br i1 %tobool, label %if.then, label %if.end // // Or the following simpler case: // %expval = call i1 @llvm.expect.i1(i1 %cmp, i1 1) // br i1 %expval, label %if.then, label %if.end CallInst *CI; ICmpInst *CmpI = dyn_cast<ICmpInst>(BI->getCondition()); if (!CmpI) { CI = dyn_cast<CallInst>(BI->getCondition()); } else { if (CmpI->getPredicate() != CmpInst::ICMP_NE) return false; CI = dyn_cast<CallInst>(CmpI->getOperand(0)); } if (!CI) return false; Function *Fn = CI->getCalledFunction(); if (!Fn || Fn->getIntrinsicID() != Intrinsic::expect) return false; Value *ArgValue = CI->getArgOperand(0); ConstantInt *ExpectedValue = dyn_cast<ConstantInt>(CI->getArgOperand(1)); if (!ExpectedValue) return false; MDBuilder MDB(CI->getContext()); MDNode *Node; // If expect value is equal to 1 it means that we are more likely to take // branch 0, in other case more likely is branch 1. if (ExpectedValue->isOne()) Node = MDB.createBranchWeights(LikelyBranchWeight, UnlikelyBranchWeight); else Node = MDB.createBranchWeights(UnlikelyBranchWeight, LikelyBranchWeight); BI->setMetadata(LLVMContext::MD_prof, Node); if (CmpI) CmpI->setOperand(0, ArgValue); else BI->setCondition(ArgValue); return true; }
void TempScopInfo::buildAffineCondition(Value &V, bool inverted, Comparison **Comp, TempScop &Scop) const { Region &R = Scop.getMaxRegion(); ParamSetType &Params = Scop.getParamSet(); if (ConstantInt *C = dyn_cast<ConstantInt>(&V)) { // If this is always true condition, we will create 1 >= 0, // otherwise we will create 1 == 0. SCEVAffFunc *AffLHS = new SCEVAffFunc(SE->getConstant(C->getType(), 0), SCEVAffFunc::Eq, R, Params, LI, SE); SCEVAffFunc *AffRHS = new SCEVAffFunc(SE->getConstant(C->getType(), 1), SCEVAffFunc::Eq, R, Params, LI, SE); if (C->isOne() == inverted) *Comp = new Comparison(AffRHS, AffLHS, ICmpInst::ICMP_NE); else *Comp = new Comparison(AffLHS, AffLHS, ICmpInst::ICMP_EQ); return; } ICmpInst *ICmp = dyn_cast<ICmpInst>(&V); assert(ICmp && "Only ICmpInst of constant as condition supported!"); const SCEV *LHS = SE->getSCEV(ICmp->getOperand(0)), *RHS = SE->getSCEV(ICmp->getOperand(1)); ICmpInst::Predicate Pred = ICmp->getPredicate(); // Invert the predicate if needed. if (inverted) Pred = ICmpInst::getInversePredicate(Pred); SCEVAffFunc *AffLHS = new SCEVAffFunc(LHS, SCEVAffFunc::Eq, R, Params, LI, SE); SCEVAffFunc *AffRHS = new SCEVAffFunc(RHS, SCEVAffFunc::Eq, R, Params, LI, SE); switch (Pred) { case ICmpInst::ICMP_UGT: case ICmpInst::ICMP_UGE: case ICmpInst::ICMP_ULT: case ICmpInst::ICMP_ULE: // TODO: At the moment we need to see everything as signed. This is an // correctness issue that needs to be solved. //AffLHS->setUnsigned(); //AffRHS->setUnsigned(); break; default: break; } *Comp = new Comparison(AffLHS, AffRHS, Pred); }
void TempScopInfo::buildAffineCondition(Value &V, bool inverted, Comparison **Comp) const { if (ConstantInt *C = dyn_cast<ConstantInt>(&V)) { // If this is always true condition, we will create 0 <= 1, // otherwise we will create 0 >= 1. const SCEV *LHS = SE->getConstant(C->getType(), 0); const SCEV *RHS = SE->getConstant(C->getType(), 1); if (C->isOne() == inverted) *Comp = new Comparison(LHS, RHS, ICmpInst::ICMP_SLE); else *Comp = new Comparison(LHS, RHS, ICmpInst::ICMP_SGE); return; } ICmpInst *ICmp = dyn_cast<ICmpInst>(&V); assert(ICmp && "Only ICmpInst of constant as condition supported!"); Loop *L = LI->getLoopFor(ICmp->getParent()); const SCEV *LHS = SE->getSCEVAtScope(ICmp->getOperand(0), L); const SCEV *RHS = SE->getSCEVAtScope(ICmp->getOperand(1), L); ICmpInst::Predicate Pred = ICmp->getPredicate(); // Invert the predicate if needed. if (inverted) Pred = ICmpInst::getInversePredicate(Pred); switch (Pred) { case ICmpInst::ICMP_UGT: case ICmpInst::ICMP_UGE: case ICmpInst::ICMP_ULT: case ICmpInst::ICMP_ULE: // TODO: At the moment we need to see everything as signed. This is an // correctness issue that needs to be solved. // AffLHS->setUnsigned(); // AffRHS->setUnsigned(); break; default: break; } *Comp = new Comparison(LHS, RHS, Pred); }
bool LowerExpectIntrinsic::HandleIfExpect(BranchInst *BI) { if (BI->isUnconditional()) return false; // Handle non-optimized IR code like: // %expval = call i64 @llvm.expect.i64.i64(i64 %conv1, i64 1) // %tobool = icmp ne i64 %expval, 0 // br i1 %tobool, label %if.then, label %if.end ICmpInst *CmpI = dyn_cast<ICmpInst>(BI->getCondition()); if (!CmpI || CmpI->getPredicate() != CmpInst::ICMP_NE) return false; CallInst *CI = dyn_cast<CallInst>(CmpI->getOperand(0)); if (!CI) return false; Function *Fn = CI->getCalledFunction(); if (!Fn || Fn->getIntrinsicID() != Intrinsic::expect) return false; Value *ArgValue = CI->getArgOperand(0); ConstantInt *ExpectedValue = dyn_cast<ConstantInt>(CI->getArgOperand(1)); if (!ExpectedValue) return false; LLVMContext &Context = CI->getContext(); const Type *Int32Ty = Type::getInt32Ty(Context); bool Likely = ExpectedValue->isOne(); // If expect value is equal to 1 it means that we are more likely to take // branch 0, in other case more likely is branch 1. Value *Ops[] = { MDString::get(Context, "branch_weights"), ConstantInt::get(Int32Ty, Likely ? LikelyBranchWeight : UnlikelyBranchWeight), ConstantInt::get(Int32Ty, Likely ? UnlikelyBranchWeight : LikelyBranchWeight) }; MDNode *WeightsNode = MDNode::get(Context, Ops); BI->setMetadata(LLVMContext::MD_prof, WeightsNode); CmpI->setOperand(0, ArgValue); return true; }
void IndVarSimplify::EliminateIVComparisons() { SmallVector<WeakVH, 16> DeadInsts; // Look for ICmp users. for (IVUsers::iterator I = IU->begin(), E = IU->end(); I != E; ++I) { IVStrideUse &UI = *I; ICmpInst *ICmp = dyn_cast<ICmpInst>(UI.getUser()); if (!ICmp) continue; bool Swapped = UI.getOperandValToReplace() == ICmp->getOperand(1); ICmpInst::Predicate Pred = ICmp->getPredicate(); if (Swapped) Pred = ICmpInst::getSwappedPredicate(Pred); // Get the SCEVs for the ICmp operands. const SCEV *S = IU->getReplacementExpr(UI); const SCEV *X = SE->getSCEV(ICmp->getOperand(!Swapped)); // Simplify unnecessary loops away. const Loop *ICmpLoop = LI->getLoopFor(ICmp->getParent()); S = SE->getSCEVAtScope(S, ICmpLoop); X = SE->getSCEVAtScope(X, ICmpLoop); // If the condition is always true or always false, replace it with // a constant value. if (SE->isKnownPredicate(Pred, S, X)) ICmp->replaceAllUsesWith(ConstantInt::getTrue(ICmp->getContext())); else if (SE->isKnownPredicate(ICmpInst::getInversePredicate(Pred), S, X)) ICmp->replaceAllUsesWith(ConstantInt::getFalse(ICmp->getContext())); else continue; DEBUG(dbgs() << "INDVARS: Eliminated comparison: " << *ICmp << '\n'); DeadInsts.push_back(ICmp); } // Now that we're done iterating through lists, clean up any instructions // which are now dead. while (!DeadInsts.empty()) if (Instruction *Inst = dyn_cast_or_null<Instruction>(&*DeadInsts.pop_back_val())) RecursivelyDeleteTriviallyDeadInstructions(Inst); }
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 RelativeMinMax::getMinMax(Expr Ex, Expr &Min, Expr &Max) { if (Ex.isConstant()) { Min = Ex; Max = Ex; } else if (Ex.isSymbol()) { // Bounds of induction variables have special treatment. if (PHINode *Phi = dyn_cast<PHINode>(Ex.getSymbolValue())) { if (Loop *L = LIE_->getLoopForInductionVariable(Phi)) { Expr IndvarStart, IndvarEnd, IndvarStep; LIE_->getLoopInfo(L, Phi, IndvarStart, IndvarEnd, IndvarStep); BranchInst *BI = cast<BranchInst>(L->getExitingBlock()->getTerminator()); ICmpInst *ICI = cast<ICmpInst>(BI->getCondition()); Expr MinStart, MaxStart, MinEnd, MaxEnd; if (!getMinMax(IndvarStart, MinStart, MaxStart) || !getMinMax(IndvarEnd, MinEnd, MaxEnd)) { RMM_DEBUG(dbgs() << "RelativeMinMax: Could not infer min/max for " << IndvarStart << " and/or" << IndvarEnd << "\n"); return false; } // FIXME: we should wrap the loop in a conditional so that the following // min/max assumptions always hold. switch (ICI->getPredicate()) { case CmpInst::ICMP_SLT: case CmpInst::ICMP_ULT: case CmpInst::ICMP_SLE: case CmpInst::ICMP_ULE: Min = MinStart; Max = MaxEnd; break; case CmpInst::ICMP_SGT: case CmpInst::ICMP_UGT: case CmpInst::ICMP_UGE: case CmpInst::ICMP_SGE: Min = MaxStart; Max = MinEnd; break; default: llvm_unreachable("Invalid comparison predicate"); } RMM_DEBUG(dbgs() << "RelativeMinMax: min/max for induction variable " << *Phi << ": " << Min << ", " << Max << "\n"); return true; } } Min = Ex; Max = Ex; } else if (Ex.isAdd()) { for (auto SubEx : Ex) { Expr TmpMin, TmpMax; if (!getMinMax(SubEx, TmpMin, TmpMax)) { RMM_DEBUG(dbgs() << "RelativeMinMax: Could not infer min/max for " << SubEx << "\n"); return false; } addMinMax(TmpMin, TmpMax, Min, Max, Min, Max); } } else if (Ex.isMul()) { Min = Expr::InvalidExpr(); for (auto SubEx : Ex) { Expr TmpMin, TmpMax; if (!getMinMax(SubEx, TmpMin, TmpMax)) { RMM_DEBUG(dbgs() << "RelativeMinMax: Could not infer min/max for " << SubEx << "\n"); return false; } if (!Min.isValid()) { Min = TmpMin; Max = TmpMax; } else { mulMinMax(TmpMin, TmpMax, Min, Max, Min, Max); } } } else if (Ex.isPow()) { if (!Ex.getPowExp().isConstant()) { RMM_DEBUG(dbgs() << "RelativeMinMax: non-constant exponent\n"); return false; } Expr BaseMin, BaseMax; if (!getMinMax(Ex.getPowBase(), BaseMin, BaseMax)) { RMM_DEBUG(dbgs() << "RelativeMinMax: Could not infer min/max for " << Ex.getPowBase() << "\n"); return false; } if (Ex.getPowExp().isPositive()) { Min = BaseMin ^ Ex.getPowExp(); Max = BaseMax ^ Ex.getPowExp(); } else { Min = BaseMax ^ Ex.getPowExp(); Max = BaseMin ^ Ex.getPowExp(); } } else if (Ex.isMin()) { Expr MinFirst, MinSecond, Bogus; getMinMax(Ex.at(0), MinFirst, Bogus); getMinMax(Ex.at(1), MinSecond, Bogus); Min = Max = MinFirst.min(MinSecond); } else if (Ex.isMax()) { Expr MaxFirst, MaxSecond, Bogus; getMinMax(Ex.at(0), MaxFirst, Bogus); getMinMax(Ex.at(1), MaxSecond, Bogus); Min = Max = MaxFirst.max(MaxSecond); } else { RMM_DEBUG(dbgs() << "RelativeMinMax: unhandled expression: " << Ex << "\n"); return false; } return true; }
bool CallAnalyzer::visitICmp(ICmpInst &I) { Value *LHS = I.getOperand(0), *RHS = I.getOperand(1); // First try to handle simplified comparisons. if (!isa<Constant>(LHS)) if (Constant *SimpleLHS = SimplifiedValues.lookup(LHS)) LHS = SimpleLHS; if (!isa<Constant>(RHS)) if (Constant *SimpleRHS = SimplifiedValues.lookup(RHS)) RHS = SimpleRHS; if (Constant *CLHS = dyn_cast<Constant>(LHS)) if (Constant *CRHS = dyn_cast<Constant>(RHS)) if (Constant *C = ConstantExpr::getICmp(I.getPredicate(), CLHS, CRHS)) { SimplifiedValues[&I] = C; return true; } // Otherwise look for a comparison between constant offset pointers with // a common base. Value *LHSBase, *RHSBase; APInt LHSOffset, RHSOffset; llvm::tie(LHSBase, LHSOffset) = ConstantOffsetPtrs.lookup(LHS); if (LHSBase) { llvm::tie(RHSBase, RHSOffset) = ConstantOffsetPtrs.lookup(RHS); if (RHSBase && LHSBase == RHSBase) { // We have common bases, fold the icmp to a constant based on the // offsets. Constant *CLHS = ConstantInt::get(LHS->getContext(), LHSOffset); Constant *CRHS = ConstantInt::get(RHS->getContext(), RHSOffset); if (Constant *C = ConstantExpr::getICmp(I.getPredicate(), CLHS, CRHS)) { SimplifiedValues[&I] = C; ++NumConstantPtrCmps; return true; } } } // If the comparison is an equality comparison with null, we can simplify it // for any alloca-derived argument. if (I.isEquality() && isa<ConstantPointerNull>(I.getOperand(1))) if (isAllocaDerivedArg(I.getOperand(0))) { // We can actually predict the result of comparisons between an // alloca-derived value and null. Note that this fires regardless of // SROA firing. bool IsNotEqual = I.getPredicate() == CmpInst::ICMP_NE; SimplifiedValues[&I] = IsNotEqual ? ConstantInt::getTrue(I.getType()) : ConstantInt::getFalse(I.getType()); return true; } // Finally check for SROA candidates in comparisons. Value *SROAArg; DenseMap<Value *, int>::iterator CostIt; if (lookupSROAArgAndCost(I.getOperand(0), SROAArg, CostIt)) { if (isa<ConstantPointerNull>(I.getOperand(1))) { accumulateSROACost(CostIt, InlineConstants::InstrCost); return true; } disableSROA(CostIt); } return false; }
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; }
int BranchProbabilities::CheckIntegerHeuristic() { // Heuristic fails if the last instruction is not a conditional branch BranchInst *BI = dyn_cast<BranchInst>(_TI); if ((!BI) || (BI->isUnconditional())) return -1; // All integer 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); // If neither is a constant, nothing to do if (!isa<ConstantInt>(v[0]) && !isa<ConstantInt>(v[1])) return -1; // If we're dealing with something other than ints, nothing to do if (!isa<IntegerType>(v[0]->getType())) return -1; // Get comparison ICmpInst::Predicate pred = icmp->getPredicate(); // Eq and Not Eq are easy cases if (pred == ICmpInst::ICMP_EQ) return 1; else if (pred == ICmpInst::ICMP_NE) return 0; ConstantInt *CI = dyn_cast<ConstantInt>(v[1]); // If the right side isn't a constant, swap the predicate so we can pretend if (!CI) { pred = icmp->getSwappedPredicate(); CI = cast<ConstantInt>(v[0]); } // Choose the appropriate branch depending on the const val and predicate if (CI->isZero()) { switch (pred) { case ICmpInst::ICMP_UGE: assert("UGE zero always returns true"); return -1; case ICmpInst::ICMP_ULT: assert("ULT zero always returns false"); return -1; case ICmpInst::ICMP_UGT: case ICmpInst::ICMP_SGT: case ICmpInst::ICMP_SGE: return 0; case ICmpInst::ICMP_ULE: case ICmpInst::ICMP_SLT: case ICmpInst::ICMP_SLE: return 1; default: return -1; } } else if (CI->isOne()) { switch (pred) { case ICmpInst::ICMP_UGE: case ICmpInst::ICMP_SGE: return 0; case ICmpInst::ICMP_ULT: case ICmpInst::ICMP_SLT: return 1; default: return -1; } } else if (CI->isAllOnesValue()) { switch (pred) { case ICmpInst::ICMP_SGT: return 0; case ICmpInst::ICMP_SLE: return 1; default: return -1; } } return -1; }
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; }
/// MatchSelectPattern - Pattern match integer [SU]MIN, [SU]MAX, and ABS idioms, /// returning the kind and providing the out parameter results if we /// successfully match. static SelectPatternFlavor MatchSelectPattern(Value *V, Value *&LHS, Value *&RHS) { SelectInst *SI = dyn_cast<SelectInst>(V); if (!SI) return SPF_UNKNOWN; ICmpInst *ICI = dyn_cast<ICmpInst>(SI->getCondition()); if (!ICI) return SPF_UNKNOWN; ICmpInst::Predicate Pred = ICI->getPredicate(); Value *CmpLHS = ICI->getOperand(0); Value *CmpRHS = ICI->getOperand(1); Value *TrueVal = SI->getTrueValue(); Value *FalseVal = SI->getFalseValue(); LHS = CmpLHS; RHS = CmpRHS; // (icmp X, Y) ? X : Y if (TrueVal == CmpLHS && FalseVal == CmpRHS) { switch (Pred) { default: return SPF_UNKNOWN; // Equality. case ICmpInst::ICMP_UGT: case ICmpInst::ICMP_UGE: return SPF_UMAX; case ICmpInst::ICMP_SGT: case ICmpInst::ICMP_SGE: return SPF_SMAX; case ICmpInst::ICMP_ULT: case ICmpInst::ICMP_ULE: return SPF_UMIN; case ICmpInst::ICMP_SLT: case ICmpInst::ICMP_SLE: return SPF_SMIN; } } // (icmp X, Y) ? Y : X if (TrueVal == CmpRHS && FalseVal == CmpLHS) { switch (Pred) { default: return SPF_UNKNOWN; // Equality. case ICmpInst::ICMP_UGT: case ICmpInst::ICMP_UGE: return SPF_UMIN; case ICmpInst::ICMP_SGT: case ICmpInst::ICMP_SGE: return SPF_SMIN; case ICmpInst::ICMP_ULT: case ICmpInst::ICMP_ULE: return SPF_UMAX; case ICmpInst::ICMP_SLT: case ICmpInst::ICMP_SLE: return SPF_SMAX; } } if (ConstantInt *C1 = dyn_cast<ConstantInt>(CmpRHS)) { if ((CmpLHS == TrueVal && match(FalseVal, m_Neg(m_Specific(CmpLHS)))) || (CmpLHS == FalseVal && match(TrueVal, m_Neg(m_Specific(CmpLHS))))) { // ABS(X) ==> (X >s 0) ? X : -X and (X >s -1) ? X : -X // NABS(X) ==> (X >s 0) ? -X : X and (X >s -1) ? -X : X if (Pred == ICmpInst::ICMP_SGT && (C1->isZero() || C1->isMinusOne())) { return (CmpLHS == TrueVal) ? SPF_ABS : SPF_NABS; } // ABS(X) ==> (X <s 0) ? -X : X and (X <s 1) ? -X : X // NABS(X) ==> (X <s 0) ? X : -X and (X <s 1) ? X : -X if (Pred == ICmpInst::ICMP_SLT && (C1->isZero() || C1->isOne())) { return (CmpLHS == FalseVal) ? SPF_ABS : SPF_NABS; } } } // TODO: (X > 4) ? X : 5 --> (X >= 5) ? X : 5 --> MAX(X, 5) return SPF_UNKNOWN; }
Value* LoopTripCount::insertTripCount(Loop* L, Instruction* InsertPos) { // inspired from Loop::getCanonicalInductionVariable BasicBlock *H = L->getHeader(); BasicBlock* LoopPred = L->getLoopPredecessor(); BasicBlock* startBB = NULL;//which basicblock stores start value int OneStep = 0;// the extra add or plus step for calc Assert(LoopPred, "Require Loop has a Pred"); DEBUG(errs()<<"loop depth:"<<L->getLoopDepth()<<"\n"); /** whats difference on use of predecessor and preheader??*/ //RET_ON_FAIL(self->getLoopLatch()&&self->getLoopPreheader()); //assert(self->getLoopLatch() && self->getLoopPreheader() && "need loop simplify form" ); ret_null_fail(L->getLoopLatch(), "need loop simplify form"); BasicBlock* TE = NULL;//True Exit SmallVector<BasicBlock*,4> Exits; L->getExitingBlocks(Exits); if(Exits.size()==1) TE = Exits.front(); else{ if(std::find(Exits.begin(),Exits.end(),L->getLoopLatch())!=Exits.end()) TE = L->getLoopLatch(); else{ SmallVector<llvm::Loop::Edge,4> ExitEdges; L->getExitEdges(ExitEdges); //stl 用法,先把所有满足条件的元素(出口的结束符是不可到达)移动到数组的末尾,再统一删除 ExitEdges.erase(std::remove_if(ExitEdges.begin(), ExitEdges.end(), [](llvm::Loop::Edge& I){ return isa<UnreachableInst>(I.second->getTerminator()); }), ExitEdges.end()); if(ExitEdges.size()==1) TE = const_cast<BasicBlock*>(ExitEdges.front().first); } } //process true exit ret_null_fail(TE, "need have a true exit"); Instruction* IndOrNext = NULL; Value* END = NULL; //终止块的终止指令:分情况讨论branchinst,switchinst; //跳转指令br bool a1,a2;condition<-->bool if(isa<BranchInst>(TE->getTerminator())){ const BranchInst* EBR = cast<BranchInst>(TE->getTerminator()); Assert(EBR->isConditional(), "end branch is not conditional"); ICmpInst* EC = dyn_cast<ICmpInst>(EBR->getCondition()); if(EC->getPredicate() == EC->ICMP_SGT){ Assert(!L->contains(EBR->getSuccessor(0)), *EBR<<":abnormal exit with great than");//终止块的终止指令---->跳出执行循环外的指令 OneStep += 1; } else if(EC->getPredicate() == EC->ICMP_EQ) Assert(!L->contains(EBR->getSuccessor(0)), *EBR<<":abnormal exit with great than"); else if(EC->getPredicate() == EC->ICMP_SLT) { ret_null_fail(!L->contains(EBR->getSuccessor(1)), *EBR<<":abnormal exit with less than"); } else { ret_null_fail(0, *EC<<" unknow combination of end condition"); } IndOrNext = dyn_cast<Instruction>(castoff(EC->getOperand(0)));//去掉类型转化 END = EC->getOperand(1); DEBUG(errs()<<"end value:"<<*EC<<"\n"); }else if(isa<SwitchInst>(TE->getTerminator())){ SwitchInst* ESW = const_cast<SwitchInst*>(cast<SwitchInst>(TE->getTerminator())); IndOrNext = dyn_cast<Instruction>(castoff(ESW->getCondition())); for(auto I = ESW->case_begin(),E = ESW->case_end();I!=E;++I){ if(!L->contains(I.getCaseSuccessor())){ ret_null_fail(!END,""); assert(!END && "shouldn't have two ends"); END = I.getCaseValue(); } } DEBUG(errs()<<"end value:"<<*ESW<<"\n"); }else{ assert(0 && "unknow terminator type"); } ret_null_fail(L->isLoopInvariant(END), "end value should be loop invariant");//至此得END值 Value* start = NULL; Value* ind = NULL; Instruction* next = NULL; bool addfirst = false;//add before icmp ed DISABLE(errs()<<*IndOrNext<<"\n"); if(isa<LoadInst>(IndOrNext)){ //memory depend analysis Value* PSi = IndOrNext->getOperand(0);//point type Step.i int SICount[2] = {0};//store in predecessor count,store in loop body count for( auto I = PSi->use_begin(),E = PSi->use_end();I!=E;++I){ DISABLE(errs()<<**I<<"\n"); StoreInst* SI = dyn_cast<StoreInst>(*I); if(!SI || SI->getOperand(1) != PSi) continue; if(!start&&L->isLoopInvariant(SI->getOperand(0))) { if(SI->getParent() != LoopPred) if(std::find(pred_begin(LoopPred),pred_end(LoopPred),SI->getParent()) == pred_end(LoopPred)) continue; start = SI->getOperand(0); startBB = SI->getParent(); ++SICount[0]; } Instruction* SI0 = dyn_cast<Instruction>(SI->getOperand(0)); if(L->contains(SI) && SI0 && SI0->getOpcode() == Instruction::Add){ next = SI0; ++SICount[1]; } } Assert(SICount[0]==1 && SICount[1]==1, ""); ind = IndOrNext; }else{ if(isa<PHINode>(IndOrNext)){ PHINode* PHI = cast<PHINode>(IndOrNext); ind = IndOrNext; if(castoff(PHI->getIncomingValue(0)) == castoff(PHI->getIncomingValue(1)) && PHI->getParent() != H) ind = castoff(PHI->getIncomingValue(0)); addfirst = false; }else if(IndOrNext->getOpcode() == Instruction::Add){ next = IndOrNext; addfirst = true; }else{ Assert(0 ,"unknow how to analysis"); } for(auto I = H->begin();isa<PHINode>(I);++I){ PHINode* P = cast<PHINode>(I); if(ind && P == ind){ //start = P->getIncomingValueForBlock(L->getLoopPredecessor()); start = tryFindStart(P, L, startBB); next = dyn_cast<Instruction>(P->getIncomingValueForBlock(L->getLoopLatch())); }else if(next && P->getIncomingValueForBlock(L->getLoopLatch()) == next){ //start = P->getIncomingValueForBlock(L->getLoopPredecessor()); start = tryFindStart(P, L, startBB); ind = P; } } } Assert(start ,"couldn't find a start value"); //process complex loops later //DEBUG(if(L->getLoopDepth()>1 || !L->getSubLoops().empty()) return NULL); DEBUG(errs()<<"start value:"<<*start<<"\n"); DEBUG(errs()<<"ind value:"<<*ind<<"\n"); DEBUG(errs()<<"next value:"<<*next<<"\n"); //process non add later unsigned next_phi_idx = 0; ConstantInt* Step = NULL,*PrevStep = NULL;/*only used if next is phi node*/ ret_null_fail(next, ""); PHINode* next_phi = dyn_cast<PHINode>(next); do{ if(next_phi) { next = dyn_cast<Instruction>(next_phi->getIncomingValue(next_phi_idx)); ret_null_fail(next, ""); DEBUG(errs()<<"next phi "<<next_phi_idx<<":"<<*next<<"\n"); if(Step&&PrevStep){ Assert(Step->getSExtValue() == PrevStep->getSExtValue(),""); } PrevStep = Step; } Assert(next->getOpcode() == Instruction::Add , "why induction increment is not Add"); Assert(next->getOperand(0) == ind ,"why induction increment is not add it self"); Step = dyn_cast<ConstantInt>(next->getOperand(1)); Assert(Step,""); }while(next_phi && ++next_phi_idx<next_phi->getNumIncomingValues()); //RET_ON_FAIL(Step->equalsInt(1)); //assert(VERBOSE(Step->equalsInt(1),Step) && "why induction increment number is not 1"); Value* RES = NULL; //if there are no predecessor, we can insert code into start value basicblock IRBuilder<> Builder(InsertPos); Assert(start->getType()->isIntegerTy() && END->getType()->isIntegerTy() , " why increment is not integer type"); if(start->getType() != END->getType()){ start = Builder.CreateCast(CastInst::getCastOpcode(start, false, END->getType(), false),start,END->getType()); } if(Step->getType() != END->getType()){ //Because Step is a Constant, so it casted is constant Step = dyn_cast<ConstantInt>(Builder.CreateCast(CastInst::getCastOpcode(Step, false, END->getType(), false),Step,END->getType())); AssertRuntime(Step); } if(Step->isMinusOne()) RES = Builder.CreateSub(start,END); else//Step Couldn't be zero RES = Builder.CreateSub(END, start); if(addfirst) OneStep -= 1; if(Step->isMinusOne()) OneStep*=-1; assert(OneStep<=1 && OneStep>=-1); RES = (OneStep==1)?Builder.CreateAdd(RES,Step):(OneStep==-1)?Builder.CreateSub(RES, Step):RES; if(!Step->isMinusOne()&&!Step->isOne()) RES = Builder.CreateSDiv(RES, Step); RES->setName(H->getName()+".tc"); return RES; }
bool AlignmentFromAssumptions::extractAlignmentInfo(CallInst *I, Value *&AAPtr, const SCEV *&AlignSCEV, const SCEV *&OffSCEV) { // An alignment assume must be a statement about the least-significant // bits of the pointer being zero, possibly with some offset. ICmpInst *ICI = dyn_cast<ICmpInst>(I->getArgOperand(0)); if (!ICI) return false; // This must be an expression of the form: x & m == 0. if (ICI->getPredicate() != ICmpInst::ICMP_EQ) return false; // Swap things around so that the RHS is 0. Value *CmpLHS = ICI->getOperand(0); Value *CmpRHS = ICI->getOperand(1); const SCEV *CmpLHSSCEV = SE->getSCEV(CmpLHS); const SCEV *CmpRHSSCEV = SE->getSCEV(CmpRHS); if (CmpLHSSCEV->isZero()) std::swap(CmpLHS, CmpRHS); else if (!CmpRHSSCEV->isZero()) return false; BinaryOperator *CmpBO = dyn_cast<BinaryOperator>(CmpLHS); if (!CmpBO || CmpBO->getOpcode() != Instruction::And) return false; // Swap things around so that the right operand of the and is a constant // (the mask); we cannot deal with variable masks. Value *AndLHS = CmpBO->getOperand(0); Value *AndRHS = CmpBO->getOperand(1); const SCEV *AndLHSSCEV = SE->getSCEV(AndLHS); const SCEV *AndRHSSCEV = SE->getSCEV(AndRHS); if (isa<SCEVConstant>(AndLHSSCEV)) { std::swap(AndLHS, AndRHS); std::swap(AndLHSSCEV, AndRHSSCEV); } const SCEVConstant *MaskSCEV = dyn_cast<SCEVConstant>(AndRHSSCEV); if (!MaskSCEV) return false; // The mask must have some trailing ones (otherwise the condition is // trivial and tells us nothing about the alignment of the left operand). unsigned TrailingOnes = MaskSCEV->getAPInt().countTrailingOnes(); if (!TrailingOnes) return false; // Cap the alignment at the maximum with which LLVM can deal (and make sure // we don't overflow the shift). uint64_t Alignment; TrailingOnes = std::min(TrailingOnes, unsigned(sizeof(unsigned) * CHAR_BIT - 1)); Alignment = std::min(1u << TrailingOnes, +Value::MaximumAlignment); Type *Int64Ty = Type::getInt64Ty(I->getParent()->getParent()->getContext()); AlignSCEV = SE->getConstant(Int64Ty, Alignment); // The LHS might be a ptrtoint instruction, or it might be the pointer // with an offset. AAPtr = nullptr; OffSCEV = nullptr; if (PtrToIntInst *PToI = dyn_cast<PtrToIntInst>(AndLHS)) { AAPtr = PToI->getPointerOperand(); OffSCEV = SE->getZero(Int64Ty); } else if (const SCEVAddExpr* AndLHSAddSCEV = dyn_cast<SCEVAddExpr>(AndLHSSCEV)) { // Try to find the ptrtoint; subtract it and the rest is the offset. for (SCEVAddExpr::op_iterator J = AndLHSAddSCEV->op_begin(), JE = AndLHSAddSCEV->op_end(); J != JE; ++J) if (const SCEVUnknown *OpUnk = dyn_cast<SCEVUnknown>(*J)) if (PtrToIntInst *PToI = dyn_cast<PtrToIntInst>(OpUnk->getValue())) { AAPtr = PToI->getPointerOperand(); OffSCEV = SE->getMinusSCEV(AndLHSAddSCEV, *J); break; } } if (!AAPtr) return false; // Sign extend the offset to 64 bits (so that it is like all of the other // expressions). unsigned OffSCEVBits = OffSCEV->getType()->getPrimitiveSizeInBits(); if (OffSCEVBits < 64) OffSCEV = SE->getSignExtendExpr(OffSCEV, Int64Ty); else if (OffSCEVBits > 64) return false; AAPtr = AAPtr->stripPointerCasts(); return true; }
bool AtomicExpandLoadLinked::expandAtomicCmpXchg(AtomicCmpXchgInst *CI) { AtomicOrdering SuccessOrder = CI->getSuccessOrdering(); AtomicOrdering FailureOrder = CI->getFailureOrdering(); Value *Addr = CI->getPointerOperand(); BasicBlock *BB = CI->getParent(); Function *F = BB->getParent(); LLVMContext &Ctx = F->getContext(); // Given: cmpxchg some_op iN* %addr, iN %desired, iN %new success_ord fail_ord // // The full expansion we produce is: // [...] // fence? // cmpxchg.start: // %loaded = @load.linked(%addr) // %should_store = icmp eq %loaded, %desired // br i1 %should_store, label %cmpxchg.trystore, // label %cmpxchg.end/%cmpxchg.barrier // cmpxchg.trystore: // %stored = @store_conditional(%new, %addr) // %try_again = icmp i32 ne %stored, 0 // br i1 %try_again, label %loop, label %cmpxchg.end // cmpxchg.barrier: // fence? // br label %cmpxchg.end // cmpxchg.end: // [...] BasicBlock *ExitBB = BB->splitBasicBlock(CI, "cmpxchg.end"); auto BarrierBB = BasicBlock::Create(Ctx, "cmpxchg.barrier", F, ExitBB); auto TryStoreBB = BasicBlock::Create(Ctx, "cmpxchg.trystore", F, BarrierBB); auto LoopBB = BasicBlock::Create(Ctx, "cmpxchg.start", F, TryStoreBB); // This grabs the DebugLoc from CI IRBuilder<> Builder(CI); // The split call above "helpfully" added a branch at the end of BB (to the // wrong place), but we might want a fence too. It's easiest to just remove // the branch entirely. std::prev(BB->end())->eraseFromParent(); Builder.SetInsertPoint(BB); AtomicOrdering MemOpOrder = insertLeadingFence(Builder, SuccessOrder); Builder.CreateBr(LoopBB); // Start the main loop block now that we've taken care of the preliminaries. Builder.SetInsertPoint(LoopBB); Value *Loaded = TLI->emitLoadLinked(Builder, Addr, MemOpOrder); Value *ShouldStore = Builder.CreateICmpEQ(Loaded, CI->getCompareOperand(), "should_store"); // If the the cmpxchg doesn't actually need any ordering when it fails, we can // jump straight past that fence instruction (if it exists). BasicBlock *FailureBB = FailureOrder == Monotonic ? ExitBB : BarrierBB; Builder.CreateCondBr(ShouldStore, TryStoreBB, FailureBB); Builder.SetInsertPoint(TryStoreBB); Value *StoreSuccess = TLI->emitStoreConditional( Builder, CI->getNewValOperand(), Addr, MemOpOrder); Value *TryAgain = Builder.CreateICmpNE( StoreSuccess, ConstantInt::get(Type::getInt32Ty(Ctx), 0), "success"); Builder.CreateCondBr(TryAgain, LoopBB, BarrierBB); // Make sure later instructions don't get reordered with a fence if necessary. Builder.SetInsertPoint(BarrierBB); insertTrailingFence(Builder, SuccessOrder); Builder.CreateBr(ExitBB); // Finally, we have control-flow based knowledge of whether the cmpxchg // succeeded or not. We expose this to later passes by converting any // subsequent "icmp eq/ne %loaded, %oldval" into a use of an appropriate PHI. // Setup the builder so we can create any PHIs we need. Builder.SetInsertPoint(FailureBB, FailureBB->begin()); BasicBlock *SuccessBB = FailureOrder == Monotonic ? BarrierBB : TryStoreBB; PHINode *Success = 0, *Failure = 0; // Look for any users of the cmpxchg that are just comparing the loaded value // against the desired one, and replace them with the CFG-derived version. for (auto User : CI->users()) { ICmpInst *ICmp = dyn_cast<ICmpInst>(User); if (!ICmp) continue; // Because we know ICmp uses CI, we only need one operand to be the old // value. if (ICmp->getOperand(0) != CI->getCompareOperand() && ICmp->getOperand(1) != CI->getCompareOperand()) continue; if (ICmp->getPredicate() == CmpInst::ICMP_EQ) { if (!Success) { Success = Builder.CreatePHI(Type::getInt1Ty(Ctx), 2); Success->addIncoming(ConstantInt::getTrue(Ctx), SuccessBB); Success->addIncoming(ConstantInt::getFalse(Ctx), LoopBB); } ICmp->replaceAllUsesWith(Success); } else if (ICmp->getPredicate() == CmpInst::ICMP_NE) { if (!Failure) { Failure = Builder.CreatePHI(Type::getInt1Ty(Ctx), 2); Failure->addIncoming(ConstantInt::getFalse(Ctx), SuccessBB); Failure->addIncoming(ConstantInt::getTrue(Ctx), LoopBB); } ICmp->replaceAllUsesWith(Failure); } } CI->replaceAllUsesWith(Loaded); CI->eraseFromParent(); return true; }
/// getEdgeValue - This method attempts to infer more complex bool LazyValueInfoCache::getEdgeValue(Value *Val, BasicBlock *BBFrom, BasicBlock *BBTo, LVILatticeVal &Result) { // If already a constant, there is nothing to compute. if (Constant *VC = dyn_cast<Constant>(Val)) { Result = LVILatticeVal::get(VC); return true; } // TODO: Handle more complex conditionals. If (v == 0 || v2 < 1) is false, we // know that v != 0. if (BranchInst *BI = dyn_cast<BranchInst>(BBFrom->getTerminator())) { // If this is a conditional branch and only one successor goes to BBTo, then // we maybe able to infer something from the condition. if (BI->isConditional() && BI->getSuccessor(0) != BI->getSuccessor(1)) { bool isTrueDest = BI->getSuccessor(0) == BBTo; assert(BI->getSuccessor(!isTrueDest) == BBTo && "BBTo isn't a successor of BBFrom"); // If V is the condition of the branch itself, then we know exactly what // it is. if (BI->getCondition() == Val) { Result = LVILatticeVal::get(ConstantInt::get( Type::getInt1Ty(Val->getContext()), isTrueDest)); return true; } // If the condition of the branch is an equality comparison, we may be // able to infer the value. ICmpInst *ICI = dyn_cast<ICmpInst>(BI->getCondition()); if (ICI && ICI->getOperand(0) == Val && isa<Constant>(ICI->getOperand(1))) { if (ICI->isEquality()) { // We know that V has the RHS constant if this is a true SETEQ or // false SETNE. if (isTrueDest == (ICI->getPredicate() == ICmpInst::ICMP_EQ)) Result = LVILatticeVal::get(cast<Constant>(ICI->getOperand(1))); else Result = LVILatticeVal::getNot(cast<Constant>(ICI->getOperand(1))); return true; } if (ConstantInt *CI = dyn_cast<ConstantInt>(ICI->getOperand(1))) { // Calculate the range of values that would satisfy the comparison. ConstantRange CmpRange(CI->getValue(), CI->getValue()+1); ConstantRange TrueValues = ConstantRange::makeICmpRegion(ICI->getPredicate(), CmpRange); // If we're interested in the false dest, invert the condition. if (!isTrueDest) TrueValues = TrueValues.inverse(); // Figure out the possible values of the query BEFORE this branch. if (!hasBlockValue(Val, BBFrom)) { BlockValueStack.push(std::make_pair(BBFrom, Val)); return false; } LVILatticeVal InBlock = getBlockValue(Val, BBFrom); if (!InBlock.isConstantRange()) { Result = LVILatticeVal::getRange(TrueValues); return true; } // Find all potential values that satisfy both the input and output // conditions. ConstantRange PossibleValues = TrueValues.intersectWith(InBlock.getConstantRange()); Result = LVILatticeVal::getRange(PossibleValues); return true; } } } } // If the edge was formed by a switch on the value, then we may know exactly // what it is. if (SwitchInst *SI = dyn_cast<SwitchInst>(BBFrom->getTerminator())) { if (SI->getCondition() == Val) { // We don't know anything in the default case. if (SI->getDefaultDest() == BBTo) { Result.markOverdefined(); return true; } // We only know something if there is exactly one value that goes from // BBFrom to BBTo. unsigned NumEdges = 0; ConstantInt *EdgeVal = 0; for (unsigned i = 1, e = SI->getNumSuccessors(); i != e; ++i) { if (SI->getSuccessor(i) != BBTo) continue; if (NumEdges++) break; EdgeVal = SI->getCaseValue(i); } assert(EdgeVal && "Missing successor?"); if (NumEdges == 1) { Result = LVILatticeVal::get(EdgeVal); return true; } } } // Otherwise see if the value is known in the block. if (hasBlockValue(Val, BBFrom)) { Result = getBlockValue(Val, BBFrom); return true; } BlockValueStack.push(std::make_pair(BBFrom, Val)); return false; }
bool BranchProbabilityInfo::calcZeroHeuristics(const BasicBlock *BB, const TargetLibraryInfo *TLI) { const 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->getValue().isPowerOf2()) return false; // Check if the LHS is the return value of a library function LibFunc Func = NumLibFuncs; if (TLI) if (CallInst *Call = dyn_cast<CallInst>(CI->getOperand(0))) if (Function *CalledFn = Call->getCalledFunction()) TLI->getLibFunc(*CalledFn, Func); bool isProb; if (Func == LibFunc_strcasecmp || Func == LibFunc_strcmp || Func == LibFunc_strncasecmp || Func == LibFunc_strncmp || Func == LibFunc_memcmp) { // strcmp and similar functions return zero, negative, or positive, if the // first string is equal, less, or greater than the second. We consider it // likely that the strings are not equal, so a comparison with zero is // probably false, but also a comparison with any other number is also // probably false given that what exactly is returned for nonzero values is // not specified. Any kind of comparison other than equality we know // nothing about. switch (CI->getPredicate()) { case CmpInst::ICMP_EQ: isProb = false; break; case CmpInst::ICMP_NE: isProb = true; break; default: return false; } } else 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->isMinusOne()) { 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; }
/// \brief Compute the value of Val on the edge BBFrom -> BBTo. Returns false if /// Val is not constrained on the edge. static bool getEdgeValueLocal(Value *Val, BasicBlock *BBFrom, BasicBlock *BBTo, LVILatticeVal &Result) { // TODO: Handle more complex conditionals. If (v == 0 || v2 < 1) is false, we // know that v != 0. if (BranchInst *BI = dyn_cast<BranchInst>(BBFrom->getTerminator())) { // If this is a conditional branch and only one successor goes to BBTo, then // we maybe able to infer something from the condition. if (BI->isConditional() && BI->getSuccessor(0) != BI->getSuccessor(1)) { bool isTrueDest = BI->getSuccessor(0) == BBTo; assert(BI->getSuccessor(!isTrueDest) == BBTo && "BBTo isn't a successor of BBFrom"); // If V is the condition of the branch itself, then we know exactly what // it is. if (BI->getCondition() == Val) { Result = LVILatticeVal::get(ConstantInt::get( Type::getInt1Ty(Val->getContext()), isTrueDest)); return true; } // If the condition of the branch is an equality comparison, we may be // able to infer the value. ICmpInst *ICI = dyn_cast<ICmpInst>(BI->getCondition()); if (ICI && isa<Constant>(ICI->getOperand(1))) { if (ICI->isEquality() && ICI->getOperand(0) == Val) { // We know that V has the RHS constant if this is a true SETEQ or // false SETNE. if (isTrueDest == (ICI->getPredicate() == ICmpInst::ICMP_EQ)) Result = LVILatticeVal::get(cast<Constant>(ICI->getOperand(1))); else Result = LVILatticeVal::getNot(cast<Constant>(ICI->getOperand(1))); return true; } // Recognize the range checking idiom that InstCombine produces. // (X-C1) u< C2 --> [C1, C1+C2) ConstantInt *NegOffset = 0; if (ICI->getPredicate() == ICmpInst::ICMP_ULT) match(ICI->getOperand(0), m_Add(m_Specific(Val), m_ConstantInt(NegOffset))); ConstantInt *CI = dyn_cast<ConstantInt>(ICI->getOperand(1)); if (CI && (ICI->getOperand(0) == Val || NegOffset)) { // Calculate the range of values that would satisfy the comparison. ConstantRange CmpRange(CI->getValue()); ConstantRange TrueValues = ConstantRange::makeICmpRegion(ICI->getPredicate(), CmpRange); if (NegOffset) // Apply the offset from above. TrueValues = TrueValues.subtract(NegOffset->getValue()); // If we're interested in the false dest, invert the condition. if (!isTrueDest) TrueValues = TrueValues.inverse(); Result = LVILatticeVal::getRange(TrueValues); return true; } } } } // If the edge was formed by a switch on the value, then we may know exactly // what it is. if (SwitchInst *SI = dyn_cast<SwitchInst>(BBFrom->getTerminator())) { if (SI->getCondition() != Val) return false; bool DefaultCase = SI->getDefaultDest() == BBTo; unsigned BitWidth = Val->getType()->getIntegerBitWidth(); ConstantRange EdgesVals(BitWidth, DefaultCase/*isFullSet*/); for (SwitchInst::CaseIt i = SI->case_begin(), e = SI->case_end(); i != e; ++i) { ConstantRange EdgeVal(i.getCaseValue()->getValue()); if (DefaultCase) { // It is possible that the default destination is the destination of // some cases. There is no need to perform difference for those cases. if (i.getCaseSuccessor() != BBTo) EdgesVals = EdgesVals.difference(EdgeVal); } else if (i.getCaseSuccessor() == BBTo) EdgesVals = EdgesVals.unionWith(EdgeVal); } Result = LVILatticeVal::getRange(EdgesVals); return true; } return false; }
bool RippleElimination::runOnFunction(Function &F) { std::vector<Instruction*> **RippleLists; unsigned ListID = 0; unsigned NumofLists = 0; RippleLists = new std::vector<Instruction*>*; RippleLists[ListID] = new std::vector<Instruction*>; RippleLists[ListID]->clear(); //errs() << "RippleLists[0] size:" << RippleLists[0]->size() << "\n"; for (Function::iterator BB = F.begin(), BE = F.end(); BB != BE; ++BB) { BasicBlock *BC = dyn_cast<BasicBlock>(BB); //==> how to get an identifier of a BB? for (BasicBlock::iterator IB = BB->begin(), IE = BB->end(); IB != IE; ++IB) { // The dyn_cast<> operator is a "checking cast" operation. It checks to // see if the operand is of the specified type, and if so, returns a // pointer to it (this operator does not work with references). If the // operand is not of the correct type, a null pointer is returned. Instruction *IT = dyn_cast<Instruction>(IB); Instruction *BackIT; ICmpInst * cmpinst = dyn_cast<ICmpInst>(IT); if(cmpinst!=NULL) { // If not a NULL pointer errs()<< "!!!! In CMP Oh yeah!!!!"<<"\n"; switch(cmpinst->getPredicate()){ case ICmpInst::ICMP_SLE: { errs()<<"QQQQ SLE\n"; } break; case ICmpInst::ICMP_SLT: { Value *op0 = IT->getOperand(0); Instruction * op0_inst = dyn_cast<Instruction> (op0); Value *op0_op1 = op0_inst->getOperand(1); ConstantInt *op0_op1_const = dyn_cast<ConstantInt>(op0_op1); APInt b = op0_op1_const->getValue(); ConstantInt *op1 = dyn_cast<ConstantInt>(IT->getOperand(1)); APInt a = op1->getValue(); errs() << "CMP Value0 ::" << b.getLimitedValue() << "\n"; errs() << "CMP Value1 ::" << a.getLimitedValue() << "\n"; int aa = a.getLimitedValue(); int bb = b.getLimitedValue(); // errs()<<a.getBitWidth()<<"\n"; errs()<<"The flag adder should be "<<(int)ceil(log(aa)/log(2))<<" bit adder\n"; errs()<<"QQQQ SLT\n"; } break; default: break; } } // Get Binary Operator Instruction::Add if(dyn_cast<BinaryOperator>(IT)) { // If not a NULL pointer BinaryOperator* Inst = dyn_cast<BinaryOperator>(IT); // errs()<<"Zhuangh put: "<<Inst->getOpcode()<<"\n"; if (Inst->getOpcode() == Instruction::Add) { Value *Op0 = IT->getOperand(0); Value *Op1 = IT->getOperand(1); //errs() << "Add Value0 ::" << *Op0 << "\n"; //errs() << "Add Value1 ::" << *Op1 << "\n"; if(RippleLists[0]->empty()) { RippleLists[0]->push_back(IT); } else { BackIT = dyn_cast<Instruction>(RippleLists[0]->back()); //errs() << "BackIT :" << *BackIT << "\n"; if(BackIT->getName().equals(Op0->getName()) || BackIT->getName().equals(Op1->getName())) { RippleLists[0]->push_back(IT); } } } } } // End Instruction iterator if(RippleLists[0]->size() < 2) RippleLists[0]->clear(); // No ripple detected for(std::vector<Instruction*>::iterator RplIT = RippleLists[0]->begin(); RplIT != RippleLists[0]->end(); ++RplIT){ Instruction *Inst = dyn_cast<Instruction>(*RplIT); errs() << "Ripple Operations:" << *Inst << "\n"; //errs() << "Name:" << Inst->getName().str() << " "; //errs() << "Op0:" << Inst->getOperand(0)->getName().str() << " "; //errs() << "Op1:" << Inst->getOperand(1)->getName().str() << "\n"; //It->eraseFromParent(); } //errs() << "RippleLists[0] size:" << RippleLists[0]->size() << "\n"; errs() << "\n"; RippleLists[0]->clear(); } // End basic block iterator return true; }
// addEdgesFor // Creates a node for I and inserts edges from the created node to the // appropriate node of other values. void IneqGraph::addEdgesFor(Instruction *I) { if (I->getType()->isPointerTy()) return; Range RI = RA->getRange(I); if (!RI.getLower().isMinSignedValue()) addMayEdge(AlfaConst, I, -RI.getLower().getSExtValue()); if (!RI.getUpper().isMaxSignedValue()) addMayEdge(I, AlfaConst, RI.getUpper().getSExtValue()); // TODO: Handle multiplication, remainder and division instructions. switch (I->getOpcode()) { case Instruction::SExt: case Instruction::ZExt: case Instruction::Trunc: case Instruction::BitCast: addMayEdge(I, I->getOperand(0), 0); addMayEdge(I->getOperand(0), I, 0); break; case Instruction::Add: // a = b + c // ==> a <= b + sup(c) // ==> a <= c + sup(b) // ==> b <= a - inf(c) // ==> c <= a - inf(b) { Value *A = I->getOperand(0); Value *B = I->getOperand(1); Range AR = RA->getRange(A); Range BR = RA->getRange(B); if (!isa<ConstantInt>(B) && !AR.getUpper().isMaxSignedValue()) addMayEdge(I, B, AR.getUpper()); if (!isa<ConstantInt>(A) && !BR.getUpper().isMaxSignedValue()) addMayEdge(I, A, BR.getUpper()); if (!isa<ConstantInt>(A) && !BR.getLower().isMinSignedValue()) addMayEdge(A, I, -BR.getUpper()); if (!isa<ConstantInt>(B) && !AR.getLower().isMinSignedValue()) addMayEdge(B, I, -AR.getUpper()); break; } case Instruction::Sub: // a = b - c // ==> a <= b - inf(c) { Value *A = I->getOperand(0); Value *B = I->getOperand(1); Range AR = RA->getRange(A); Range BR = RA->getRange(B); if (!isa<ConstantInt>(A) && !BR.getLower().isMinSignedValue()) addMayEdge(I, A, -BR.getLower()); break; } case Instruction::Br: // if (a > b) { // a1 = sigma(a) // b1 = sigma(b) { BranchInst *BI = cast<BranchInst>(I); ICmpInst *Cmp = dyn_cast<ICmpInst>(I->getOperand(0)); if (!Cmp) break; Value *L = Cmp->getOperand(0); DEBUG(dbgs() << "IneqGraph: L: " << *L << "\n"); Value *R = Cmp->getOperand(1); DEBUG(dbgs() << "IneqGraph: R: " << *R << "\n"); Value *LSigma = VS->findSigma(L, BI->getSuccessor(0), BI->getParent()); DEBUG(dbgs() << "IneqGraph: LSigma: " << *LSigma << "\n"); Value *RSigma = VS->findSigma(R, BI->getSuccessor(0), BI->getParent()); DEBUG(dbgs() << "IneqGraph: RSigma: " << *RSigma << "\n"); Value *LSExtSigma = VS->findSExtSigma(L, BI->getSuccessor(0), BI->getParent()); DEBUG(dbgs() << "IneqGraph: LSExtSigma: " << *LSExtSigma << "\n"); Value *RSExtSigma = VS->findSExtSigma(R, BI->getSuccessor(0), BI->getParent()); DEBUG(dbgs() << "IneqGraph: RSExtSigma: " << *RSExtSigma << "\n"); switch (Cmp->getPredicate()) { case ICmpInst::ICMP_SLT: DEBUG(dbgs() << "IneqGraph: SLT:\n"); if (!isa<ConstantInt>(R) && LSigma) { if (RSigma) addMayEdge(LSigma, RSigma, -1); if (RSExtSigma) addMayEdge(LSigma, RSExtSigma, -1); } if (!isa<ConstantInt>(R) && LSExtSigma && LSExtSigma != LSigma) { if (RSigma) addMayEdge(LSExtSigma, RSigma, -1); if (RSExtSigma) addMayEdge(LSExtSigma, RSExtSigma, -1); } break; case ICmpInst::ICMP_SLE: DEBUG(dbgs() << "IneqGraph: SLE:\n"); if (!isa<ConstantInt>(R) && LSigma && RSigma) addMayEdge(LSigma, RSigma, 0); if (!isa<ConstantInt>(R) && (LSExtSigma != LSigma || RSExtSigma != RSigma)) addMayEdge(LSExtSigma, RSExtSigma, 0); break; default: break; } break; } case Instruction::PHI: { PHINode *Phi = cast<PHINode>(I); for (unsigned Idx = 0; Idx < Phi->getNumIncomingValues(); ++Idx) { addMustEdge(Phi, Phi->getIncomingValue(Idx), 0); } break; } case Instruction::Call: { CallInst *CI = cast<CallInst>(I); if (Function *F = CI->getCalledFunction()) { unsigned Idx = 0; for (Function::arg_iterator AI = F->arg_begin(), AE = F->arg_end(); AI != AE; ++AI, ++Idx) { addMustEdge(&(*AI), CI->getArgOperand(Idx), 0); } } break; } } }