/// Utility function that checks whether \p VPBlockVec has duplicate
/// VPBlockBases.
static bool hasDuplicates(const SmallVectorImpl<VPBlockBase *> &VPBlockVec) {
  SmallDenseSet<const VPBlockBase *, 8> VPBlockSet;
  for (const auto *Block : VPBlockVec) {
    if (VPBlockSet.count(Block))
      return true;
    VPBlockSet.insert(Block);
  }
  return false;
}
Exemple #2
0
/// Sort local variables so that variables appearing inside of helper
/// expressions come first.
static SmallVector<DbgVariable *, 8>
sortLocalVars(SmallVectorImpl<DbgVariable *> &Input) {
  SmallVector<DbgVariable *, 8> Result;
  SmallVector<PointerIntPair<DbgVariable *, 1>, 8> WorkList;
  // Map back from a DIVariable to its containing DbgVariable.
  SmallDenseMap<const DILocalVariable *, DbgVariable *> DbgVar;
  // Set of DbgVariables in Result.
  SmallDenseSet<DbgVariable *, 8> Visited;
  // For cycle detection.
  SmallDenseSet<DbgVariable *, 8> Visiting;

  // Initialize the worklist and the DIVariable lookup table.
  for (auto Var : reverse(Input)) {
    DbgVar.insert({Var->getVariable(), Var});
    WorkList.push_back({Var, 0});
  }

  // Perform a stable topological sort by doing a DFS.
  while (!WorkList.empty()) {
    auto Item = WorkList.back();
    DbgVariable *Var = Item.getPointer();
    bool visitedAllDependencies = Item.getInt();
    WorkList.pop_back();

    // Dependency is in a different lexical scope or a global.
    if (!Var)
      continue;

    // Already handled.
    if (Visited.count(Var))
      continue;

    // Add to Result if all dependencies are visited.
    if (visitedAllDependencies) {
      Visited.insert(Var);
      Result.push_back(Var);
      continue;
    }

    // Detect cycles.
    auto Res = Visiting.insert(Var);
    if (!Res.second) {
      assert(false && "dependency cycle in local variables");
      return Result;
    }

    // Push dependencies and this node onto the worklist, so that this node is
    // visited again after all of its dependencies are handled.
    WorkList.push_back({Var, 1});
    for (auto *Dependency : dependencies(Var)) {
      auto Dep = dyn_cast_or_null<const DILocalVariable>(Dependency);
      WorkList.push_back({DbgVar[Dep], 0});
    }
  }
  return Result;
}
Exemple #3
0
unsigned DWARFVerifier::verifyAbbrevSection(const DWARFDebugAbbrev *Abbrev) {
  unsigned NumErrors = 0;
  if (Abbrev) {
    const DWARFAbbreviationDeclarationSet *AbbrDecls =
        Abbrev->getAbbreviationDeclarationSet(0);
    for (auto AbbrDecl : *AbbrDecls) {
      SmallDenseSet<uint16_t> AttributeSet;
      for (auto Attribute : AbbrDecl.attributes()) {
        auto Result = AttributeSet.insert(Attribute.Attr);
        if (!Result.second) {
          error() << "Abbreviation declaration contains multiple "
                  << AttributeString(Attribute.Attr) << " attributes.\n";
          AbbrDecl.dump(OS);
          ++NumErrors;
        }
      }
    }
  }
  return NumErrors;
}
bool llvm::MergeBlockIntoPredecessor(BasicBlock *BB, DominatorTree *DT,
                                     LoopInfo *LI,
                                     MemoryDependenceResults *MemDep) {
  // Don't merge away blocks who have their address taken.
  if (BB->hasAddressTaken()) return false;

  // Can't merge if there are multiple predecessors, or no predecessors.
  BasicBlock *PredBB = BB->getUniquePredecessor();
  if (!PredBB) return false;

  // Don't break self-loops.
  if (PredBB == BB) return false;
  // Don't break unwinding instructions.
  if (PredBB->getTerminator()->isExceptional())
    return false;

  succ_iterator SI(succ_begin(PredBB)), SE(succ_end(PredBB));
  BasicBlock *OnlySucc = BB;
  for (; SI != SE; ++SI)
    if (*SI != OnlySucc) {
      OnlySucc = nullptr;     // There are multiple distinct successors!
      break;
    }

  // Can't merge if there are multiple successors.
  if (!OnlySucc) return false;

  // Can't merge if there is PHI loop.
  for (PHINode &PN : BB->phis())
    for (Value *IncValue : PN.incoming_values())
      if (IncValue == &PN)
        return false;

  // Begin by getting rid of unneeded PHIs.
  SmallVector<Value *, 4> IncomingValues;
  if (isa<PHINode>(BB->front())) {
    for (PHINode &PN : BB->phis())
      if (PN.getIncomingValue(0) != &PN)
        IncomingValues.push_back(PN.getIncomingValue(0));
    FoldSingleEntryPHINodes(BB, MemDep);
  }

  // Delete the unconditional branch from the predecessor...
  PredBB->getInstList().pop_back();

  // Make all PHI nodes that referred to BB now refer to Pred as their
  // source...
  BB->replaceAllUsesWith(PredBB);

  // Move all definitions in the successor to the predecessor...
  PredBB->getInstList().splice(PredBB->end(), BB->getInstList());

  // Eliminate duplicate dbg.values describing the entry PHI node post-splice.
  for (auto *Incoming : IncomingValues) {
    if (isa<Instruction>(Incoming)) {
      SmallVector<DbgValueInst *, 2> DbgValues;
      SmallDenseSet<std::pair<DILocalVariable *, DIExpression *>, 2>
          DbgValueSet;
      llvm::findDbgValues(DbgValues, Incoming);
      for (auto &DVI : DbgValues) {
        auto R = DbgValueSet.insert({DVI->getVariable(), DVI->getExpression()});
        if (!R.second)
          DVI->eraseFromParent();
      }
    }
  }

  // Inherit predecessors name if it exists.
  if (!PredBB->hasName())
    PredBB->takeName(BB);

  // Finally, erase the old block and update dominator info.
  if (DT)
    if (DomTreeNode *DTN = DT->getNode(BB)) {
      DomTreeNode *PredDTN = DT->getNode(PredBB);
      SmallVector<DomTreeNode *, 8> Children(DTN->begin(), DTN->end());
      for (DomTreeNode *DI : Children)
        DT->changeImmediateDominator(DI, PredDTN);

      DT->eraseNode(BB);
    }

  if (LI)
    LI->removeBlock(BB);

  if (MemDep)
    MemDep->invalidateCachedPredecessors();

  BB->eraseFromParent();
  return true;
}