// Adds the edge F -> T with weight Weight. APInt IneqGraph::findShortestPath(Value *F, Value *T) { DEBUG(dbgs() << "IneqGraph: findShortestPath: " << *F << " ==> " << *T << "\n"); if (isa<ConstantInt>(F) || isa<ConstantInt>(T)) { APInt RangeF = getUpper(F); APInt RangeT = getLower(T); DEBUG(dbgs() << "Ranges: " << RangeF << " and " << RangeT << "\n"); if (RangeF.isMaxSignedValue() || RangeF.isMinSignedValue() || RangeT.isMaxSignedValue() || RangeT.isMinSignedValue()) return APInt::getSignedMaxValue(64); return RangeF.sextOrSelf(64) - RangeT.sextOrSelf(64); } GraphNode *FN = getOrCreateNode(F); GraphNode *TN = getOrCreateNode(T); return FN->findShortestPath(TN); }
APInt GraphNode::findShortestPath(GraphNode *Dest, SetVector<GraphNode*> Visited) { if (Dest == this) { DEBUG(dbgs() << "IneqGraph: Reached: " << *Dest->getValue() << "\n"); return APInt(64, 0, true); } DEBUG(dbgs() << "IneqGraph: Node: " << *V << "\n"); if (Visited.count(this)) { DEBUG(dbgs() << "IneqGraph: Visited\n"); return APInt::getSignedMaxValue(64); //(64, , true); } Visited.insert(this); APInt MayMin = APInt::getSignedMaxValue(64); for (may_iterator It = may_begin(), E = may_end(); It != E; ++It) { APInt Total = It->getToEdge()->findShortestPath(Dest, Visited); if (Total.slt(MayMin)) MayMin = Total + It->getWeight(); } //DEBUG(dbgs() << "IneqGraph: Node: " << *V << ", MayMin: " << MayMin << "\n"); APInt MustMax = APInt::getSignedMinValue(64); for (must_iterator It = must_begin(), E = must_end(); It != E; ++It) { APInt Total = It->getToEdge()->findShortestPath(Dest, Visited); if (MustMax.slt(Total)) MustMax = Total; } // DEBUG(dbgs() << "IneqGraph: Node: " << *V << ", MustMax: " << MustMax << "\n"); if (MustMax.isMinSignedValue()) { //DEBUG(dbgs() << "IneqGraph: Node: " << *V << ", Distance: " << MayMin << "\n"); DEBUG(dbgs() << "IneqGraph: Ret: " << MayMin << "\n"); return MayMin; } else { APInt Min = MustMax.slt(MayMin) ? MustMax : MayMin; //DEBUG(dbgs() << "IneqGraph: Node: " << *V << ", Distance: " << Min << "\n"); DEBUG(dbgs() << "IneqGraph: Ret: " << Min << "\n"); return Min; } }