Esempio n. 1
0
  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]);
    }
  }
Esempio n. 2
0
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));
      }
    }
  }
}
Esempio n. 4
0
  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]);
    }
  }