Пример #1
0
unsigned
DWARFVerifier::verifyDebugNamesCULists(const DWARFDebugNames &AccelTable) {
  // A map from CU offset to the (first) Name Index offset which claims to index
  // this CU.
  DenseMap<uint32_t, uint32_t> CUMap;
  const uint32_t NotIndexed = std::numeric_limits<uint32_t>::max();

  CUMap.reserve(DCtx.getNumCompileUnits());
  for (const auto &CU : DCtx.compile_units())
    CUMap[CU->getOffset()] = NotIndexed;

  unsigned NumErrors = 0;
  for (const DWARFDebugNames::NameIndex &NI : AccelTable) {
    if (NI.getCUCount() == 0) {
      error() << formatv("Name Index @ {0:x} does not index any CU\n",
                         NI.getUnitOffset());
      ++NumErrors;
      continue;
    }
    for (uint32_t CU = 0, End = NI.getCUCount(); CU < End; ++CU) {
      uint32_t Offset = NI.getCUOffset(CU);
      auto Iter = CUMap.find(Offset);

      if (Iter == CUMap.end()) {
        error() << formatv(
            "Name Index @ {0:x} references a non-existing CU @ {1:x}\n",
            NI.getUnitOffset(), Offset);
        ++NumErrors;
        continue;
      }

      if (Iter->second != NotIndexed) {
        error() << formatv("Name Index @ {0:x} references a CU @ {1:x}, but "
                          "this CU is already indexed by Name Index @ {2:x}\n",
                          NI.getUnitOffset(), Offset, Iter->second);
        continue;
      }
      Iter->second = NI.getUnitOffset();
    }
  }

  for (const auto &KV : CUMap) {
    if (KV.second == NotIndexed)
      warn() << formatv("CU @ {0:x} not covered by any Name Index\n", KV.first);
  }

  return NumErrors;
}
Пример #2
0
// Builds the graph + StratifiedSets for a function.
CFLAAResult::FunctionInfo CFLAAResult::buildSetsFrom(Function *Fn) {
  NodeMapT Map;
  GraphT Graph;
  SmallVector<Value *, 4> ReturnedValues;

  buildGraphFrom(*this, Fn, ReturnedValues, Map, Graph);

  DenseMap<GraphT::Node, Value *> NodeValueMap;
  NodeValueMap.reserve(Map.size());
  for (const auto &Pair : Map)
    NodeValueMap.insert(std::make_pair(Pair.second, Pair.first));

  const auto findValueOrDie = [&NodeValueMap](GraphT::Node Node) {
    auto ValIter = NodeValueMap.find(Node);
    assert(ValIter != NodeValueMap.end());
    return ValIter->second;
  };

  StratifiedSetsBuilder<Value *> Builder;

  SmallVector<GraphT::Node, 16> Worklist;
  for (auto &Pair : Map) {
    Worklist.clear();

    auto *Value = Pair.first;
    Builder.add(Value);
    auto InitialNode = Pair.second;
    Worklist.push_back(InitialNode);
    while (!Worklist.empty()) {
      auto Node = Worklist.pop_back_val();
      auto *CurValue = findValueOrDie(Node);
      if (canSkipAddingToSets(CurValue))
        continue;

      Optional<StratifiedAttr> MaybeCurIndex = valueToAttrIndex(CurValue);
      if (MaybeCurIndex)
        Builder.noteAttributes(CurValue, *MaybeCurIndex);

      for (const auto &EdgeTuple : Graph.edgesFor(Node)) {
        auto Weight = std::get<0>(EdgeTuple);
        auto Label = Weight.first;
        auto &OtherNode = std::get<1>(EdgeTuple);
        auto *OtherValue = findValueOrDie(OtherNode);

        if (canSkipAddingToSets(OtherValue))
          continue;

        bool Added;
        switch (directionOfEdgeType(Label)) {
        case Level::Above:
          Added = Builder.addAbove(CurValue, OtherValue);
          break;
        case Level::Below:
          Added = Builder.addBelow(CurValue, OtherValue);
          break;
        case Level::Same:
          Added = Builder.addWith(CurValue, OtherValue);
          break;
        }

        auto Aliasing = Weight.second;
        if (MaybeCurIndex)
          Aliasing.set(*MaybeCurIndex);
        if (auto MaybeOtherIndex = valueToAttrIndex(OtherValue))
          Aliasing.set(*MaybeOtherIndex);
        Builder.noteAttributes(CurValue, Aliasing);
        Builder.noteAttributes(OtherValue, Aliasing);

        if (Added)
          Worklist.push_back(OtherNode);
      }
    }
  }

  // There are times when we end up with parameters not in our graph (i.e. if
  // it's only used as the condition of a branch). Other bits of code depend on
  // things that were present during construction being present in the graph.
  // So, we add all present arguments here.
  for (auto &Arg : Fn->args()) {
    if (!Builder.add(&Arg))
      continue;

    auto Attrs = valueToAttrIndex(&Arg);
    if (Attrs.hasValue())
      Builder.noteAttributes(&Arg, *Attrs);
  }

  return FunctionInfo(Builder.build(), std::move(ReturnedValues));
}
Пример #3
0
/// Given \p BBs as input, find another set of BBs which collectively
/// dominates \p BBs and have the minimal sum of frequencies. Return the BB
/// set found in \p BBs.
static void findBestInsertionSet(DominatorTree &DT, BlockFrequencyInfo &BFI,
                                 BasicBlock *Entry,
                                 SmallPtrSet<BasicBlock *, 8> &BBs) {
  assert(!BBs.count(Entry) && "Assume Entry is not in BBs");
  // Nodes on the current path to the root.
  SmallPtrSet<BasicBlock *, 8> Path;
  // Candidates includes any block 'BB' in set 'BBs' that is not strictly
  // dominated by any other blocks in set 'BBs', and all nodes in the path
  // in the dominator tree from Entry to 'BB'.
  SmallPtrSet<BasicBlock *, 16> Candidates;
  for (auto BB : BBs) {
    // Ignore unreachable basic blocks.
    if (!DT.isReachableFromEntry(BB))
      continue;
    Path.clear();
    // Walk up the dominator tree until Entry or another BB in BBs
    // is reached. Insert the nodes on the way to the Path.
    BasicBlock *Node = BB;
    // The "Path" is a candidate path to be added into Candidates set.
    bool isCandidate = false;
    do {
      Path.insert(Node);
      if (Node == Entry || Candidates.count(Node)) {
        isCandidate = true;
        break;
      }
      assert(DT.getNode(Node)->getIDom() &&
             "Entry doens't dominate current Node");
      Node = DT.getNode(Node)->getIDom()->getBlock();
    } while (!BBs.count(Node));

    // If isCandidate is false, Node is another Block in BBs dominating
    // current 'BB'. Drop the nodes on the Path.
    if (!isCandidate)
      continue;

    // Add nodes on the Path into Candidates.
    Candidates.insert(Path.begin(), Path.end());
  }

  // Sort the nodes in Candidates in top-down order and save the nodes
  // in Orders.
  unsigned Idx = 0;
  SmallVector<BasicBlock *, 16> Orders;
  Orders.push_back(Entry);
  while (Idx != Orders.size()) {
    BasicBlock *Node = Orders[Idx++];
    for (auto ChildDomNode : DT.getNode(Node)->getChildren()) {
      if (Candidates.count(ChildDomNode->getBlock()))
        Orders.push_back(ChildDomNode->getBlock());
    }
  }

  // Visit Orders in bottom-up order.
  using InsertPtsCostPair =
      std::pair<SmallPtrSet<BasicBlock *, 16>, BlockFrequency>;

  // InsertPtsMap is a map from a BB to the best insertion points for the
  // subtree of BB (subtree not including the BB itself).
  DenseMap<BasicBlock *, InsertPtsCostPair> InsertPtsMap;
  InsertPtsMap.reserve(Orders.size() + 1);
  for (auto RIt = Orders.rbegin(); RIt != Orders.rend(); RIt++) {
    BasicBlock *Node = *RIt;
    bool NodeInBBs = BBs.count(Node);
    SmallPtrSet<BasicBlock *, 16> &InsertPts = InsertPtsMap[Node].first;
    BlockFrequency &InsertPtsFreq = InsertPtsMap[Node].second;

    // Return the optimal insert points in BBs.
    if (Node == Entry) {
      BBs.clear();
      if (InsertPtsFreq > BFI.getBlockFreq(Node) ||
          (InsertPtsFreq == BFI.getBlockFreq(Node) && InsertPts.size() > 1))
        BBs.insert(Entry);
      else
        BBs.insert(InsertPts.begin(), InsertPts.end());
      break;
    }

    BasicBlock *Parent = DT.getNode(Node)->getIDom()->getBlock();
    // Initially, ParentInsertPts is empty and ParentPtsFreq is 0. Every child
    // will update its parent's ParentInsertPts and ParentPtsFreq.
    SmallPtrSet<BasicBlock *, 16> &ParentInsertPts = InsertPtsMap[Parent].first;
    BlockFrequency &ParentPtsFreq = InsertPtsMap[Parent].second;
    // Choose to insert in Node or in subtree of Node.
    // Don't hoist to EHPad because we may not find a proper place to insert
    // in EHPad.
    // If the total frequency of InsertPts is the same as the frequency of the
    // target Node, and InsertPts contains more than one nodes, choose hoisting
    // to reduce code size.
    if (NodeInBBs ||
        (!Node->isEHPad() &&
         (InsertPtsFreq > BFI.getBlockFreq(Node) ||
          (InsertPtsFreq == BFI.getBlockFreq(Node) && InsertPts.size() > 1)))) {
      ParentInsertPts.insert(Node);
      ParentPtsFreq += BFI.getBlockFreq(Node);
    } else {
      ParentInsertPts.insert(InsertPts.begin(), InsertPts.end());
      ParentPtsFreq += InsertPtsFreq;
    }
  }
}