void AMDGPUAnnotateUniformValues::visitBranchInst(BranchInst &I) { if (I.isUnconditional()) return; Value *Cond = I.getCondition(); if (!DA->isUniform(Cond)) return; setUniformMetadata(I.getParent()->getTerminator()); }
static bool foldReturnAndProcessPred(BasicBlock *BB, ReturnInst *Ret, BasicBlock *&OldEntry, bool &TailCallsAreMarkedTail, SmallVectorImpl<PHINode *> &ArgumentPHIs, bool CannotTailCallElimCallsMarkedTail, const TargetTransformInfo *TTI) { bool Change = false; // If the return block contains nothing but the return and PHI's, // there might be an opportunity to duplicate the return in its // predecessors and perform TRC there. Look for predecessors that end // in unconditional branch and recursive call(s). SmallVector<BranchInst*, 8> UncondBranchPreds; for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI != E; ++PI) { BasicBlock *Pred = *PI; TerminatorInst *PTI = Pred->getTerminator(); if (BranchInst *BI = dyn_cast<BranchInst>(PTI)) if (BI->isUnconditional()) UncondBranchPreds.push_back(BI); } while (!UncondBranchPreds.empty()) { BranchInst *BI = UncondBranchPreds.pop_back_val(); BasicBlock *Pred = BI->getParent(); if (CallInst *CI = findTRECandidate(BI, CannotTailCallElimCallsMarkedTail, TTI)){ DEBUG(dbgs() << "FOLDING: " << *BB << "INTO UNCOND BRANCH PRED: " << *Pred); ReturnInst *RI = FoldReturnIntoUncondBranch(Ret, BB, Pred); // Cleanup: if all predecessors of BB have been eliminated by // FoldReturnIntoUncondBranch, delete it. It is important to empty it, // because the ret instruction in there is still using a value which // eliminateRecursiveTailCall will attempt to remove. if (!BB->hasAddressTaken() && pred_begin(BB) == pred_end(BB)) BB->eraseFromParent(); eliminateRecursiveTailCall(CI, RI, OldEntry, TailCallsAreMarkedTail, ArgumentPHIs, CannotTailCallElimCallsMarkedTail); ++NumRetDuped; Change = true; } } return Change; }
/// \brief Insert the missing branch conditions void StructurizeCFG::insertConditions(bool Loops) { BranchVector &Conds = Loops ? LoopConds : Conditions; Value *Default = Loops ? BoolTrue : BoolFalse; SSAUpdater PhiInserter; for (BranchVector::iterator I = Conds.begin(), E = Conds.end(); I != E; ++I) { BranchInst *Term = *I; assert(Term->isConditional()); BasicBlock *Parent = Term->getParent(); BasicBlock *SuccTrue = Term->getSuccessor(0); BasicBlock *SuccFalse = Term->getSuccessor(1); PhiInserter.Initialize(Boolean, ""); PhiInserter.AddAvailableValue(&Func->getEntryBlock(), Default); PhiInserter.AddAvailableValue(Loops ? SuccFalse : Parent, Default); BBPredicates &Preds = Loops ? LoopPreds[SuccFalse] : Predicates[SuccTrue]; NearestCommonDominator Dominator(DT); Dominator.addBlock(Parent, false); Value *ParentValue = 0; for (BBPredicates::iterator PI = Preds.begin(), PE = Preds.end(); PI != PE; ++PI) { if (PI->first == Parent) { ParentValue = PI->second; break; } PhiInserter.AddAvailableValue(PI->first, PI->second); Dominator.addBlock(PI->first); } if (ParentValue) { Term->setCondition(ParentValue); } else { if (!Dominator.wasResultExplicitMentioned()) PhiInserter.AddAvailableValue(Dominator.getResult(), Default); Term->setCondition(PhiInserter.GetValueInMiddleOfBlock(Parent)); } } }
bool TailCallElim::FoldReturnAndProcessPred(BasicBlock *BB, ReturnInst *Ret, BasicBlock *&OldEntry, bool &TailCallsAreMarkedTail, SmallVectorImpl<PHINode *> &ArgumentPHIs, bool CannotTailCallElimCallsMarkedTail) { bool Change = false; // If the return block contains nothing but the return and PHI's, // there might be an opportunity to duplicate the return in its // predecessors and perform TRC there. Look for predecessors that end // in unconditional branch and recursive call(s). SmallVector<BranchInst*, 8> UncondBranchPreds; for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI != E; ++PI) { BasicBlock *Pred = *PI; TerminatorInst *PTI = Pred->getTerminator(); if (BranchInst *BI = dyn_cast<BranchInst>(PTI)) if (BI->isUnconditional()) UncondBranchPreds.push_back(BI); } while (!UncondBranchPreds.empty()) { BranchInst *BI = UncondBranchPreds.pop_back_val(); BasicBlock *Pred = BI->getParent(); if (CallInst *CI = FindTRECandidate(BI, CannotTailCallElimCallsMarkedTail)){ DEBUG(dbgs() << "FOLDING: " << *BB << "INTO UNCOND BRANCH PRED: " << *Pred); EliminateRecursiveTailCall(CI, FoldReturnIntoUncondBranch(Ret, BB, Pred), OldEntry, TailCallsAreMarkedTail, ArgumentPHIs, CannotTailCallElimCallsMarkedTail); ++NumRetDuped; Change = true; } } return Change; }
/// shouldEliminateUnconditionalBranch - Return true if this branch looks /// attractive to eliminate. We eliminate the branch if the destination basic /// block has <= 5 instructions in it, not counting PHI nodes. In practice, /// since one of these is a terminator instruction, this means that we will add /// up to 4 instructions to the new block. /// /// We don't count PHI nodes in the count since they will be removed when the /// contents of the block are copied over. /// bool TailDup::shouldEliminateUnconditionalBranch(TerminatorInst *TI, unsigned Threshold) { BranchInst *BI = dyn_cast<BranchInst>(TI); if (!BI || !BI->isUnconditional()) return false; // Not an uncond branch! BasicBlock *Dest = BI->getSuccessor(0); if (Dest == BI->getParent()) return false; // Do not loop infinitely! // Do not inline a block if we will just get another branch to the same block! TerminatorInst *DTI = Dest->getTerminator(); if (BranchInst *DBI = dyn_cast<BranchInst>(DTI)) if (DBI->isUnconditional() && DBI->getSuccessor(0) == Dest) return false; // Do not loop infinitely! // FIXME: DemoteRegToStack cannot yet demote invoke instructions to the stack, // because doing so would require breaking critical edges. This should be // fixed eventually. if (!DTI->use_empty()) return false; // Do not bother with blocks with only a single predecessor: simplify // CFG will fold these two blocks together! pred_iterator PI = pred_begin(Dest), PE = pred_end(Dest); ++PI; if (PI == PE) return false; // Exactly one predecessor! BasicBlock::iterator I = Dest->getFirstNonPHI(); for (unsigned Size = 0; I != Dest->end(); ++I) { if (Size == Threshold) return false; // The block is too large. // Don't tail duplicate call instructions. They are very large compared to // other instructions. if (isa<CallInst>(I) || isa<InvokeInst>(I)) return false; // Also alloca and malloc. if (isa<AllocaInst>(I)) return false; // Some vector instructions can expand into a number of instructions. if (isa<ShuffleVectorInst>(I) || isa<ExtractElementInst>(I) || isa<InsertElementInst>(I)) return false; // Only count instructions that are not debugger intrinsics. if (!isa<DbgInfoIntrinsic>(I)) ++Size; } // Do not tail duplicate a block that has thousands of successors into a block // with a single successor if the block has many other predecessors. This can // cause an N^2 explosion in CFG edges (and PHI node entries), as seen in // cases that have a large number of indirect gotos. unsigned NumSuccs = DTI->getNumSuccessors(); if (NumSuccs > 8) { unsigned TooMany = 128; if (NumSuccs >= TooMany) return false; TooMany = TooMany/NumSuccs; for (; PI != PE; ++PI) if (TooMany-- == 0) return false; } // If this unconditional branch is a fall-through, be careful about // tail duplicating it. In particular, we don't want to taildup it if the // original block will still be there after taildup is completed: doing so // would eliminate the fall-through, requiring unconditional branches. Function::iterator DestI = Dest; if (&*--DestI == BI->getParent()) { // The uncond branch is a fall-through. Tail duplication of the block is // will eliminate the fall-through-ness and end up cloning the terminator // at the end of the Dest block. Since the original Dest block will // continue to exist, this means that one or the other will not be able to // fall through. One typical example that this helps with is code like: // if (a) // foo(); // if (b) // foo(); // Cloning the 'if b' block into the end of the first foo block is messy. // The messy case is when the fall-through block falls through to other // blocks. This is what we would be preventing if we cloned the block. DestI = Dest; if (++DestI != Dest->getParent()->end()) { BasicBlock *DestSucc = DestI; // If any of Dest's successors are fall-throughs, don't do this xform. for (succ_iterator SI = succ_begin(Dest), SE = succ_end(Dest); SI != SE; ++SI) if (*SI == DestSucc) return false; } } // Finally, check that we haven't redirected to this target block earlier; // there are cases where we loop forever if we don't check this (PR 2323). if (!CycleDetector.insert(Dest)) return false; return true; }
/// HandleFloatingPointIV - If the loop has floating induction variable /// then insert corresponding integer induction variable if possible. /// For example, /// for(double i = 0; i < 10000; ++i) /// bar(i) /// is converted into /// for(int i = 0; i < 10000; ++i) /// bar((double)i); /// void IndVarSimplify::HandleFloatingPointIV(Loop *L, PHINode *PN) { unsigned IncomingEdge = L->contains(PN->getIncomingBlock(0)); unsigned BackEdge = IncomingEdge^1; // Check incoming value. ConstantFP *InitValueVal = dyn_cast<ConstantFP>(PN->getIncomingValue(IncomingEdge)); int64_t InitValue; if (!InitValueVal || !ConvertToSInt(InitValueVal->getValueAPF(), InitValue)) return; // Check IV increment. Reject this PN if increment operation is not // an add or increment value can not be represented by an integer. BinaryOperator *Incr = dyn_cast<BinaryOperator>(PN->getIncomingValue(BackEdge)); if (Incr == 0 || Incr->getOpcode() != Instruction::FAdd) return; // If this is not an add of the PHI with a constantfp, or if the constant fp // is not an integer, bail out. ConstantFP *IncValueVal = dyn_cast<ConstantFP>(Incr->getOperand(1)); int64_t IncValue; if (IncValueVal == 0 || Incr->getOperand(0) != PN || !ConvertToSInt(IncValueVal->getValueAPF(), IncValue)) return; // Check Incr uses. One user is PN and the other user is an exit condition // used by the conditional terminator. Value::use_iterator IncrUse = Incr->use_begin(); Instruction *U1 = cast<Instruction>(IncrUse++); if (IncrUse == Incr->use_end()) return; Instruction *U2 = cast<Instruction>(IncrUse++); if (IncrUse != Incr->use_end()) return; // Find exit condition, which is an fcmp. If it doesn't exist, or if it isn't // only used by a branch, we can't transform it. FCmpInst *Compare = dyn_cast<FCmpInst>(U1); if (!Compare) Compare = dyn_cast<FCmpInst>(U2); if (Compare == 0 || !Compare->hasOneUse() || !isa<BranchInst>(Compare->use_back())) return; BranchInst *TheBr = cast<BranchInst>(Compare->use_back()); // We need to verify that the branch actually controls the iteration count // of the loop. If not, the new IV can overflow and no one will notice. // The branch block must be in the loop and one of the successors must be out // of the loop. assert(TheBr->isConditional() && "Can't use fcmp if not conditional"); if (!L->contains(TheBr->getParent()) || (L->contains(TheBr->getSuccessor(0)) && L->contains(TheBr->getSuccessor(1)))) return; // If it isn't a comparison with an integer-as-fp (the exit value), we can't // transform it. ConstantFP *ExitValueVal = dyn_cast<ConstantFP>(Compare->getOperand(1)); int64_t ExitValue; if (ExitValueVal == 0 || !ConvertToSInt(ExitValueVal->getValueAPF(), ExitValue)) return; // Find new predicate for integer comparison. CmpInst::Predicate NewPred = CmpInst::BAD_ICMP_PREDICATE; switch (Compare->getPredicate()) { default: return; // Unknown comparison. case CmpInst::FCMP_OEQ: case CmpInst::FCMP_UEQ: NewPred = CmpInst::ICMP_EQ; break; case CmpInst::FCMP_ONE: case CmpInst::FCMP_UNE: NewPred = CmpInst::ICMP_NE; break; case CmpInst::FCMP_OGT: case CmpInst::FCMP_UGT: NewPred = CmpInst::ICMP_SGT; break; case CmpInst::FCMP_OGE: case CmpInst::FCMP_UGE: NewPred = CmpInst::ICMP_SGE; break; case CmpInst::FCMP_OLT: case CmpInst::FCMP_ULT: NewPred = CmpInst::ICMP_SLT; break; case CmpInst::FCMP_OLE: case CmpInst::FCMP_ULE: NewPred = CmpInst::ICMP_SLE; break; } // We convert the floating point induction variable to a signed i32 value if // we can. This is only safe if the comparison will not overflow in a way // that won't be trapped by the integer equivalent operations. Check for this // now. // TODO: We could use i64 if it is native and the range requires it. // The start/stride/exit values must all fit in signed i32. if (!isInt<32>(InitValue) || !isInt<32>(IncValue) || !isInt<32>(ExitValue)) return; // If not actually striding (add x, 0.0), avoid touching the code. if (IncValue == 0) return; // Positive and negative strides have different safety conditions. if (IncValue > 0) { // If we have a positive stride, we require the init to be less than the // exit value and an equality or less than comparison. if (InitValue >= ExitValue || NewPred == CmpInst::ICMP_SGT || NewPred == CmpInst::ICMP_SGE) return; uint32_t Range = uint32_t(ExitValue-InitValue); if (NewPred == CmpInst::ICMP_SLE) { // Normalize SLE -> SLT, check for infinite loop. if (++Range == 0) return; // Range overflows. } unsigned Leftover = Range % uint32_t(IncValue); // If this is an equality comparison, we require that the strided value // exactly land on the exit value, otherwise the IV condition will wrap // around and do things the fp IV wouldn't. if ((NewPred == CmpInst::ICMP_EQ || NewPred == CmpInst::ICMP_NE) && Leftover != 0) return; // If the stride would wrap around the i32 before exiting, we can't // transform the IV. if (Leftover != 0 && int32_t(ExitValue+IncValue) < ExitValue) return; } else { // If we have a negative stride, we require the init to be greater than the // exit value and an equality or greater than comparison. if (InitValue >= ExitValue || NewPred == CmpInst::ICMP_SLT || NewPred == CmpInst::ICMP_SLE) return; uint32_t Range = uint32_t(InitValue-ExitValue); if (NewPred == CmpInst::ICMP_SGE) { // Normalize SGE -> SGT, check for infinite loop. if (++Range == 0) return; // Range overflows. } unsigned Leftover = Range % uint32_t(-IncValue); // If this is an equality comparison, we require that the strided value // exactly land on the exit value, otherwise the IV condition will wrap // around and do things the fp IV wouldn't. if ((NewPred == CmpInst::ICMP_EQ || NewPred == CmpInst::ICMP_NE) && Leftover != 0) return; // If the stride would wrap around the i32 before exiting, we can't // transform the IV. if (Leftover != 0 && int32_t(ExitValue+IncValue) > ExitValue) return; } const IntegerType *Int32Ty = Type::getInt32Ty(PN->getContext()); // Insert new integer induction variable. PHINode *NewPHI = PHINode::Create(Int32Ty, PN->getName()+".int", PN); NewPHI->addIncoming(ConstantInt::get(Int32Ty, InitValue), PN->getIncomingBlock(IncomingEdge)); Value *NewAdd = BinaryOperator::CreateAdd(NewPHI, ConstantInt::get(Int32Ty, IncValue), Incr->getName()+".int", Incr); NewPHI->addIncoming(NewAdd, PN->getIncomingBlock(BackEdge)); ICmpInst *NewCompare = new ICmpInst(TheBr, NewPred, NewAdd, ConstantInt::get(Int32Ty, ExitValue), Compare->getName()); // In the following deletions, PN may become dead and may be deleted. // Use a WeakVH to observe whether this happens. WeakVH WeakPH = PN; // Delete the old floating point exit comparison. The branch starts using the // new comparison. NewCompare->takeName(Compare); Compare->replaceAllUsesWith(NewCompare); RecursivelyDeleteTriviallyDeadInstructions(Compare); // Delete the old floating point increment. Incr->replaceAllUsesWith(UndefValue::get(Incr->getType())); RecursivelyDeleteTriviallyDeadInstructions(Incr); // If the FP induction variable still has uses, this is because something else // in the loop uses its value. In order to canonicalize the induction // variable, we chose to eliminate the IV and rewrite it in terms of an // int->fp cast. // // We give preference to sitofp over uitofp because it is faster on most // platforms. if (WeakPH) { Value *Conv = new SIToFPInst(NewPHI, PN->getType(), "indvar.conv", PN->getParent()->getFirstNonPHI()); PN->replaceAllUsesWith(Conv); RecursivelyDeleteTriviallyDeadInstructions(PN); } // Add a new IVUsers entry for the newly-created integer PHI. IU->AddUsersIfInteresting(NewPHI); }
void DSWP::buildPDG(Loop *L) { //Initialize PDG for (Loop::block_iterator bi = L->getBlocks().begin(); bi != L->getBlocks().end(); bi++) { BasicBlock *BB = *bi; for (BasicBlock::iterator ui = BB->begin(); ui != BB->end(); ui++) { Instruction *inst = &(*ui); //standardlize the name for all expr if (util.hasNewDef(inst)) { inst->setName(util.genId()); dname[inst] = inst->getNameStr(); } else { dname[inst] = util.genId(); } pdg[inst] = new vector<Edge>(); rev[inst] = new vector<Edge>(); } } //LoopInfo &li = getAnalysis<LoopInfo>(); /* * Memory dependency analysis */ MemoryDependenceAnalysis &mda = getAnalysis<MemoryDependenceAnalysis>(); for (Loop::block_iterator bi = L->getBlocks().begin(); bi != L->getBlocks().end(); bi++) { BasicBlock *BB = *bi; for (BasicBlock::iterator ii = BB->begin(); ii != BB->end(); ii++) { Instruction *inst = &(*ii); //data dependence = register dependence + memory dependence //begin register dependence for (Value::use_iterator ui = ii->use_begin(); ui != ii->use_end(); ui++) { if (Instruction *user = dyn_cast<Instruction>(*ui)) { addEdge(inst, user, REG); } } //finish register dependence //begin memory dependence MemDepResult mdr = mda.getDependency(inst); //TODO not sure clobbers mean!! if (mdr.isDef()) { Instruction *dep = mdr.getInst(); if (isa<LoadInst>(inst)) { if (isa<StoreInst>(dep)) { addEdge(dep, inst, DTRUE); //READ AFTER WRITE } } if (isa<StoreInst>(inst)) { if (isa<LoadInst>(dep)) { addEdge(dep, inst, DANTI); //WRITE AFTER READ } if (isa<StoreInst>(dep)) { addEdge(dep, inst, DOUT); //WRITE AFTER WRITE } } //READ AFTER READ IS INSERT AFTER PDG BUILD } //end memory dependence }//for ii }//for bi /* * begin control dependence */ PostDominatorTree &pdt = getAnalysis<PostDominatorTree>(); //cout << pdt.getRootNode()->getBlock()->getNameStr() << endl; /* * alien code part 1 */ LoopInfo *LI = &getAnalysis<LoopInfo>(); std::set<BranchInst*> backedgeParents; for (Loop::block_iterator bi = L->getBlocks().begin(); bi != L->getBlocks().end(); bi++) { BasicBlock *BB = *bi; for (BasicBlock::iterator ii = BB->begin(); ii != BB->end(); ii++) { Instruction *inst = ii; if (BranchInst *brInst = dyn_cast<BranchInst>(inst)) { // get the loop this instruction (and therefore basic block) belongs to Loop *instLoop = LI->getLoopFor(BB); bool branchesToHeader = false; for (int i = brInst->getNumSuccessors() - 1; i >= 0 && !branchesToHeader; i--) { // if the branch could exit, store it if (LI->getLoopFor(brInst->getSuccessor(i)) != instLoop) { branchesToHeader = true; } } if (branchesToHeader) { backedgeParents.insert(brInst); } } } } //build information for predecessor of blocks in post dominator tree for (Function::iterator bi = func->begin(); bi != func->end(); bi++) { BasicBlock *BB = bi; DomTreeNode *dn = pdt.getNode(BB); for (DomTreeNode::iterator di = dn->begin(); di != dn->end(); di++) { BasicBlock *CB = (*di)->getBlock(); pre[CB] = BB; } } // // //add dependency within a basicblock // for (Loop::block_iterator bi = L->getBlocks().begin(); bi != L->getBlocks().end(); bi++) { // BasicBlock *BB = *bi; // Instruction *pre = NULL; // for (BasicBlock::iterator ui = BB->begin(); ui != BB->end(); ui++) { // Instruction *inst = &(*ui); // if (pre != NULL) { // addEdge(pre, inst, CONTROL); // } // pre = inst; // } // } // //the special kind of dependence need loop peeling ? I don't know whether this is needed // for (Loop::block_iterator bi = L->getBlocks().begin(); bi != L->getBlocks().end(); bi++) { // BasicBlock *BB = *bi; // for (succ_iterator PI = succ_begin(BB); PI != succ_end(BB); ++PI) { // BasicBlock *succ = *PI; // // checkControlDependence(BB, succ, pdt); // } // } /* * alien code part 2 */ // add normal control dependencies // loop through each instruction for (Loop::block_iterator bbIter = L->block_begin(); bbIter != L->block_end(); ++bbIter) { BasicBlock *bb = *bbIter; // check the successors of this basic block if (BranchInst *branchInst = dyn_cast<BranchInst>(bb->getTerminator())) { if (branchInst->getNumSuccessors() > 1) { BasicBlock * succ = branchInst->getSuccessor(0); // if the successor is nested shallower than the current basic block, continue if (LI->getLoopDepth(bb) < LI->getLoopDepth(succ)) { continue; } // otherwise, add all instructions to graph as control dependence while (succ != NULL && succ != bb && LI->getLoopDepth(succ) >= LI->getLoopDepth(bb)) { Instruction *terminator = bb->getTerminator(); for (BasicBlock::iterator succInstIter = succ->begin(); &(*succInstIter) != succ->getTerminator(); ++succInstIter) { addEdge(terminator, &(*succInstIter), CONTROL); } if (BranchInst *succBrInst = dyn_cast<BranchInst>(succ->getTerminator())) { if (succBrInst->getNumSuccessors() > 1) { addEdge(terminator, succ->getTerminator(), CONTROL); } } if (BranchInst *br = dyn_cast<BranchInst>(succ->getTerminator())) { if (br->getNumSuccessors() == 1) { succ = br->getSuccessor(0); } else { succ = NULL; } } else { succ = NULL; } } } } } /* * alien code part 3 */ for (std::set<BranchInst*>::iterator exitIter = backedgeParents.begin(); exitIter != backedgeParents.end(); ++exitIter) { BranchInst *exitBranch = *exitIter; if (exitBranch->isConditional()) { BasicBlock *header = LI->getLoopFor(exitBranch->getParent())->getHeader(); for (BasicBlock::iterator ctrlIter = header->begin(); ctrlIter != header->end(); ++ctrlIter) { addEdge(exitBranch, &(*ctrlIter), CONTROL); } } } //end control dependence }
// 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; } } }