/// 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; }
/// 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; }
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; }