Ejemplo n.º 1
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);
  }
}
Ejemplo n.º 2
0
// 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));
      }
    }
  }
}