indexedGraph(const IterablePairs & pairs) { map_nodeMapIndex.reset( new map_NodeMapIndex(g) ); //A-- Compute the number of node we need std::set<IndexT> setNodes; for (typename IterablePairs::const_iterator iter = pairs.begin(); iter != pairs.end(); ++iter) { setNodes.insert(iter->first); setNodes.insert(iter->second); } //B-- Create a node graph for each element of the set for (std::set<IndexT>::const_iterator iter = setNodes.begin(); iter != setNodes.end(); ++iter) { map_size_t_to_node[*iter] = g.addNode(); (*map_nodeMapIndex) [map_size_t_to_node[*iter]] = *iter; } //C-- Add weighted edges from the pairs object for (typename IterablePairs::const_iterator iter = pairs.begin(); iter != pairs.end(); ++iter) { const IndexT i = iter->first; const IndexT j = iter->second; g.addEdge(map_size_t_to_node[i], map_size_t_to_node[j]); } }
static void addInstructionToGraph(CFLAliasAnalysis &Analysis, Instruction &Inst, SmallVectorImpl<Value *> &ReturnedValues, NodeMapT &Map, GraphT &Graph) { const auto findOrInsertNode = [&Map, &Graph](Value *Val) { auto Pair = Map.insert(std::make_pair(Val, GraphT::Node())); auto &Iter = Pair.first; if (Pair.second) { auto NewNode = Graph.addNode(); Iter->second = NewNode; } return Iter->second; }; // We don't want the edges of most "return" instructions, but we *do* want // to know what can be returned. if (isa<ReturnInst>(&Inst)) ReturnedValues.push_back(&Inst); if (!hasUsefulEdges(&Inst)) return; SmallVector<Edge, 8> Edges; argsToEdges(Analysis, &Inst, Edges); // In the case of an unused alloca (or similar), edges may be empty. Note // that it exists so we can potentially answer NoAlias. if (Edges.empty()) { auto MaybeVal = getTargetValue(&Inst); assert(MaybeVal.hasValue()); auto *Target = *MaybeVal; findOrInsertNode(Target); return; } const auto addEdgeToGraph = [&Graph, &findOrInsertNode](const Edge &E) { auto To = findOrInsertNode(E.To); auto From = findOrInsertNode(E.From); auto FlippedWeight = flipWeight(E.Weight); auto Attrs = E.AdditionalAttrs; Graph.addEdge(From, To, std::make_pair(E.Weight, Attrs), std::make_pair(FlippedWeight, Attrs)); }; SmallVector<ConstantExpr *, 4> ConstantExprs; for (const Edge &E : Edges) { addEdgeToGraph(E); if (auto *Constexpr = dyn_cast<ConstantExpr>(E.To)) ConstantExprs.push_back(Constexpr); if (auto *Constexpr = dyn_cast<ConstantExpr>(E.From)) ConstantExprs.push_back(Constexpr); } for (ConstantExpr *CE : ConstantExprs) { Edges.clear(); constexprToEdges(Analysis, *CE, Edges); std::for_each(Edges.begin(), Edges.end(), addEdgeToGraph); } }
// Aside: We may remove graph construction entirely, because it doesn't really // buy us much that we don't already have. I'd like to add interprocedural // analysis prior to this however, in case that somehow requires the graph // produced by this for efficient execution static void buildGraphFrom(CFLAliasAnalysis &Analysis, Function *Fn, SmallVectorImpl<Value *> &ReturnedValues, NodeMapT &Map, GraphT &Graph) { const auto findOrInsertNode = [&Map, &Graph](Value *Val) { auto Pair = Map.insert(std::make_pair(Val, GraphT::Node())); auto &Iter = Pair.first; if (Pair.second) { auto NewNode = Graph.addNode(); Iter->second = NewNode; } return Iter->second; }; SmallVector<Edge, 8> Edges; for (auto &Bb : Fn->getBasicBlockList()) { for (auto &Inst : Bb.getInstList()) { // We don't want the edges of most "return" instructions, but we *do* want // to know what can be returned. if (auto *Ret = dyn_cast<ReturnInst>(&Inst)) ReturnedValues.push_back(Ret); if (!hasUsefulEdges(&Inst)) continue; Edges.clear(); argsToEdges(Analysis, &Inst, Edges); // In the case of an unused alloca (or similar), edges may be empty. Note // that it exists so we can potentially answer NoAlias. if (Edges.empty()) { auto MaybeVal = getTargetValue(&Inst); assert(MaybeVal.hasValue()); auto *Target = *MaybeVal; findOrInsertNode(Target); continue; } for (const Edge &E : Edges) { auto To = findOrInsertNode(E.To); auto From = findOrInsertNode(E.From); auto FlippedWeight = flipWeight(E.Weight); auto Attrs = E.AdditionalAttrs; Graph.addEdge(From, To, std::make_pair(E.Weight, Attrs), std::make_pair(FlippedWeight, Attrs)); } } } }
indexedGraph(const IterableNodes & nodes, const IterablePairs & pairs) { map_nodeMapIndex.reset( new map_NodeMapIndex(g) ); //A-- Create a node graph for each element of the set for (typename IterableNodes::const_iterator iter = nodes.begin(); iter != nodes.end(); ++iter) { map_size_t_to_node[*iter] = g.addNode(); (*map_nodeMapIndex) [map_size_t_to_node[*iter]] = *iter; } //B-- Add weighted edges from the pairs object for (typename IterablePairs::const_iterator iter = pairs.begin(); iter != pairs.end(); ++iter) { const IndexT i = iter->first; const IndexT j = iter->second; g.addEdge(map_size_t_to_node[i], map_size_t_to_node[j]); } }