}
}
+/// \brief Locate the DISubprogram for F.
+///
+/// We look for the first instruction that has a debug annotation
+/// leading back to \p F.
+///
+/// \returns a valid DISubprogram, if found. Otherwise, it returns an empty
+/// DISubprogram.
+static const DISubprogram getDISubprogram(Function &F, const LLVMContext &Ctx) {
+ for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I) {
+ BasicBlock *B = I;
+ for (BasicBlock::iterator BI = B->begin(), BE = B->end(); BI != BE; ++BI) {
+ Instruction &Inst = *BI;
+ DebugLoc DLoc = Inst.getDebugLoc();
+ if (DLoc.isUnknown())
+ continue;
+ const MDNode *Scope = DLoc.getScopeNode(Ctx);
+ DISubprogram Subprogram = getDISubprogram(Scope);
+ return Subprogram.describes(&F) ? Subprogram : DISubprogram();
+ }
+ }
+
+ return DISubprogram();
+}
+
/// \brief Get the line number for the function header.
///
/// This looks up function \p F in the current compilation unit and
/// \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();
- }
- }
- }
+ const DISubprogram &S = getDISubprogram(F, *Ctx);
+ 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()));
return 0;
; printf("sum is %d\n", s);
; return 0;
; }
-
+;
+; Note that this test is missing the llvm.dbg.cu annotation. This emulates
+; the effect of the user having only used -fprofile-sample-use without
+; -gmlt when invoking the driver. In those cases, we need to track source
+; location information but we do not have to generate debug info in the
+; final binary.
@.str = private unnamed_addr constant [11 x i8] c"sum is %d\0A\00", align 1
; Function Attrs: nounwind uwtable
declare i32 @printf(i8*, ...) #2
-!llvm.dbg.cu = !{!0}
!llvm.module.flags = !{!8, !9}
!llvm.ident = !{!10}