void getAnalysisUsage(AnalysisUsage &AU) const override {
AU.setPreservesCFG();
- AU.addRequired<LoopInfo>();
+ AU.addRequired<LoopInfoWrapperPass>();
AU.addRequired<DominatorTreeWrapperPass>();
AU.addRequired<PostDominatorTree>();
}
unsigned getFunctionLoc(Function &F);
bool emitAnnotations(Function &F);
unsigned getInstWeight(Instruction &I);
- unsigned getBlockWeight(BasicBlock *B);
+ unsigned getBlockWeight(BasicBlock *BB);
void printEdgeWeight(raw_ostream &OS, Edge E);
void printBlockWeight(raw_ostream &OS, BasicBlock *BB);
void printBlockEquivalence(raw_ostream &OS, BasicBlock *BB);
/// \returns The profiled weight of I.
unsigned SampleProfileLoader::getInstWeight(Instruction &Inst) {
DebugLoc DLoc = Inst.getDebugLoc();
+ if (!DLoc)
+ return 0;
+
unsigned Lineno = DLoc.getLine();
if (Lineno < HeaderLineno)
return 0;
- DILocation DIL(DLoc.getAsMDNode(*Ctx));
+ DILocation DIL = DLoc.get();
int LOffset = Lineno - HeaderLineno;
unsigned Discriminator = DIL.getDiscriminator();
unsigned Weight = Samples->samplesAt(LOffset, Discriminator);
/// \brief Compute the weight of a basic block.
///
-/// The weight of basic block \p B is the maximum weight of all the
-/// instructions in B. The weight of \p B is computed and cached in
+/// The weight of basic block \p BB is the maximum weight of all the
+/// instructions in BB. The weight of \p BB is computed and cached in
/// the BlockWeights map.
///
-/// \param B The basic block to query.
+/// \param BB The basic block to query.
///
-/// \returns The computed weight of B.
-unsigned SampleProfileLoader::getBlockWeight(BasicBlock *B) {
- // If we've computed B's weight before, return it.
+/// \returns The computed weight of BB.
+unsigned SampleProfileLoader::getBlockWeight(BasicBlock *BB) {
+ // If we've computed BB's weight before, return it.
std::pair<BlockWeightMap::iterator, bool> Entry =
- BlockWeights.insert(std::make_pair(B, 0));
+ BlockWeights.insert(std::make_pair(BB, 0));
if (!Entry.second)
return Entry.first->second;
- // Otherwise, compute and cache B's weight.
+ // Otherwise, compute and cache BB's weight.
unsigned Weight = 0;
- for (BasicBlock::iterator I = B->begin(), E = B->end(); I != E; ++I) {
- unsigned InstWeight = getInstWeight(*I);
+ for (auto &I : BB->getInstList()) {
+ unsigned InstWeight = getInstWeight(I);
if (InstWeight > Weight)
Weight = InstWeight;
}
bool SampleProfileLoader::computeBlockWeights(Function &F) {
bool Changed = false;
DEBUG(dbgs() << "Block weights\n");
- for (Function::iterator B = F.begin(), E = F.end(); B != E; ++B) {
- unsigned Weight = getBlockWeight(B);
+ for (auto &BB : F) {
+ unsigned Weight = getBlockWeight(&BB);
Changed |= (Weight > 0);
- DEBUG(printBlockWeight(dbgs(), B));
+ DEBUG(printBlockWeight(dbgs(), &BB));
}
return Changed;
void SampleProfileLoader::findEquivalencesFor(
BasicBlock *BB1, SmallVector<BasicBlock *, 8> Descendants,
DominatorTreeBase<BasicBlock> *DomTree) {
- for (SmallVectorImpl<BasicBlock *>::iterator I = Descendants.begin(),
- E = Descendants.end();
- I != E; ++I) {
- BasicBlock *BB2 = *I;
+ for (auto *BB2 : Descendants) {
bool IsDomParent = DomTree->dominates(BB2, BB1);
bool IsInSameLoop = LI->getLoopFor(BB1) == LI->getLoopFor(BB2);
- if (BB1 != BB2 && VisitedBlocks.insert(BB2) && IsDomParent &&
+ if (BB1 != BB2 && VisitedBlocks.insert(BB2).second && IsDomParent &&
IsInSameLoop) {
EquivalenceClass[BB2] = BB1;
SmallVector<BasicBlock *, 8> DominatedBBs;
DEBUG(dbgs() << "\nBlock equivalence classes\n");
// Find equivalence sets based on dominance and post-dominance information.
- for (Function::iterator B = F.begin(), E = F.end(); B != E; ++B) {
- BasicBlock *BB1 = B;
+ for (auto &BB : F) {
+ BasicBlock *BB1 = &BB;
// Compute BB1's equivalence class once.
if (EquivalenceClass.count(BB1)) {
// each equivalence class has the largest weight, assign that weight
// to all the blocks in that equivalence class.
DEBUG(dbgs() << "\nAssign the same weight to all blocks in the same class\n");
- for (Function::iterator B = F.begin(), E = F.end(); B != E; ++B) {
- BasicBlock *BB = B;
+ for (auto &BI : F) {
+ BasicBlock *BB = &BI;
BasicBlock *EquivBB = EquivalenceClass[BB];
if (BB != EquivBB)
BlockWeights[BB] = BlockWeights[EquivBB];
bool SampleProfileLoader::propagateThroughEdges(Function &F) {
bool Changed = false;
DEBUG(dbgs() << "\nPropagation through edges\n");
- for (Function::iterator BI = F.begin(), EI = F.end(); BI != EI; ++BI) {
- BasicBlock *BB = BI;
+ for (auto &BI : F) {
+ BasicBlock *BB = &BI;
// Visit all the predecessor and successor edges to determine
// which ones have a weight assigned already. Note that it doesn't
if (i == 0) {
// First, visit all predecessor edges.
- for (size_t I = 0; I < Predecessors[BB].size(); I++) {
- Edge E = std::make_pair(Predecessors[BB][I], BB);
+ for (auto *Pred : Predecessors[BB]) {
+ Edge E = std::make_pair(Pred, BB);
TotalWeight += visitEdge(E, &NumUnknownEdges, &UnknownEdge);
if (E.first == E.second)
SelfReferentialEdge = E;
}
} else {
// On the second round, visit all successor edges.
- for (size_t I = 0; I < Successors[BB].size(); I++) {
- Edge E = std::make_pair(BB, Successors[BB][I]);
+ for (auto *Succ : Successors[BB]) {
+ Edge E = std::make_pair(BB, Succ);
TotalWeight += visitEdge(E, &NumUnknownEdges, &UnknownEdge);
}
}
<< " known. Set weight for block: ";
printBlockWeight(dbgs(), BB););
}
- if (VisitedBlocks.insert(BB))
+ if (VisitedBlocks.insert(BB).second)
Changed = true;
} else if (NumUnknownEdges == 1 && VisitedBlocks.count(BB)) {
// If there is a single unknown edge and the block has been
/// We are interested in unique edges. If a block B1 has multiple
/// edges to another block B2, we only add a single B1->B2 edge.
void SampleProfileLoader::buildEdges(Function &F) {
- for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I) {
- BasicBlock *B1 = I;
+ for (auto &BI : F) {
+ BasicBlock *B1 = &BI;
// Add predecessors for B1.
SmallPtrSet<BasicBlock *, 16> Visited;
llvm_unreachable("Found a stale predecessors list in a basic block.");
for (pred_iterator PI = pred_begin(B1), PE = pred_end(B1); PI != PE; ++PI) {
BasicBlock *B2 = *PI;
- if (Visited.insert(B2))
+ if (Visited.insert(B2).second)
Predecessors[B1].push_back(B2);
}
llvm_unreachable("Found a stale successors list in a basic block.");
for (succ_iterator SI = succ_begin(B1), SE = succ_end(B1); SI != SE; ++SI) {
BasicBlock *B2 = *SI;
- if (Visited.insert(B2))
+ if (Visited.insert(B2).second)
Successors[B1].push_back(B2);
}
}
/// \brief Propagate weights into edges
///
-/// The following rules are applied to every block B in the CFG:
+/// The following rules are applied to every block BB in the CFG:
///
-/// - If B has a single predecessor/successor, then the weight
+/// - If BB has a single predecessor/successor, then the weight
/// of that edge is the weight of the block.
///
/// - If all incoming or outgoing edges are known except one, and the
/// weight of the block is already known, the weight of the unknown
/// edge will be the weight of the block minus the sum of all the known
-/// edges. If the sum of all the known edges is larger than B's weight,
+/// edges. If the sum of all the known edges is larger than BB's weight,
/// we set the unknown edge weight to zero.
///
/// - If there is a self-referential edge, and the weight of the block is
// edge weights computed during propagation.
DEBUG(dbgs() << "\nPropagation complete. Setting branch weights\n");
MDBuilder MDB(F.getContext());
- for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I) {
- BasicBlock *B = I;
- TerminatorInst *TI = B->getTerminator();
+ for (auto &BI : F) {
+ BasicBlock *BB = &BI;
+ TerminatorInst *TI = BB->getTerminator();
if (TI->getNumSuccessors() == 1)
continue;
if (!isa<BranchInst>(TI) && !isa<SwitchInst>(TI))
bool AllWeightsZero = true;
for (unsigned I = 0; I < TI->getNumSuccessors(); ++I) {
BasicBlock *Succ = TI->getSuccessor(I);
- Edge E = std::make_pair(B, Succ);
+ Edge E = std::make_pair(BB, Succ);
unsigned Weight = EdgeWeights[E];
DEBUG(dbgs() << "\t"; printEdgeWeight(dbgs(), E));
Weights.push_back(Weight);
/// \returns the line number where \p F is defined. If it returns 0,
/// it means that there is no debug information available for \p F.
unsigned SampleProfileLoader::getFunctionLoc(Function &F) {
- NamedMDNode *CUNodes = F.getParent()->getNamedMetadata("llvm.dbg.cu");
- if (CUNodes) {
- for (unsigned I = 0, E1 = CUNodes->getNumOperands(); I != E1; ++I) {
- DICompileUnit CU(CUNodes->getOperand(I));
- DIArray Subprograms = CU.getSubprograms();
- for (unsigned J = 0, E2 = Subprograms.getNumElements(); J != E2; ++J) {
- DISubprogram Subprogram(Subprograms.getElement(J));
- if (Subprogram.describes(&F))
- return Subprogram.getLineNumber();
- }
- }
- }
+ DISubprogram S = getDISubprogram(&F);
+ if (S.isSubprogram())
+ return S.getLineNumber();
+ // If could not find the start of \p F, emit a diagnostic to inform the user
+ // about the missed opportunity.
F.getContext().diagnose(DiagnosticInfoSampleProfile(
- "No debug information found in function " + F.getName()));
+ "No debug information found in function " + F.getName() +
+ ": Function profile not used",
+ DS_Warning));
return 0;
}
///
/// 3- Propagation of block weights into edges. This uses a simple
/// propagation heuristic. The following rules are applied to every
-/// block B in the CFG:
+/// block BB in the CFG:
///
-/// - If B has a single predecessor/successor, then the weight
+/// - If BB has a single predecessor/successor, then the weight
/// of that edge is the weight of the block.
///
/// - If all the edges are known except one, and the weight of the
/// block is already known, the weight of the unknown edge will
/// be the weight of the block minus the sum of all the known
-/// edges. If the sum of all the known edges is larger than B's weight,
+/// edges. If the sum of all the known edges is larger than BB's weight,
/// we set the unknown edge weight to zero.
///
/// - If there is a self-referential edge, and the weight of the block is
/// work here.
///
/// Once all the branch weights are computed, we emit the MD_prof
-/// metadata on B using the computed values for each of its branches.
+/// metadata on BB using the computed values for each of its branches.
///
/// \param F The function to query.
///
"Sample Profile loader", false, false)
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
INITIALIZE_PASS_DEPENDENCY(PostDominatorTree)
-INITIALIZE_PASS_DEPENDENCY(LoopInfo)
+INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
INITIALIZE_PASS_DEPENDENCY(AddDiscriminators)
INITIALIZE_PASS_END(SampleProfileLoader, "sample-profile",
"Sample Profile loader", false, false)
bool SampleProfileLoader::doInitialization(Module &M) {
- Reader.reset(new SampleProfileReader(M, Filename));
- ProfileIsValid = Reader->load();
+ auto ReaderOrErr = SampleProfileReader::create(Filename, M.getContext());
+ if (std::error_code EC = ReaderOrErr.getError()) {
+ std::string Msg = "Could not open profile: " + EC.message();
+ M.getContext().diagnose(DiagnosticInfoSampleProfile(Filename.data(), Msg));
+ return false;
+ }
+ Reader = std::move(ReaderOrErr.get());
+ ProfileIsValid = (Reader->read() == sampleprof_error::success);
return true;
}
DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
PDT = &getAnalysis<PostDominatorTree>();
- LI = &getAnalysis<LoopInfo>();
+ LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
Ctx = &F.getParent()->getContext();
Samples = Reader->getSamplesFor(F);
if (!Samples->empty())