diff --git a/lib/Transforms/Instrumentation/GCOVProfiling.cpp b/lib/Transforms/Instrumentation/GCOVProfiling.cpp index da07ea39980..375be2a2204 100644 --- a/lib/Transforms/Instrumentation/GCOVProfiling.cpp +++ b/lib/Transforms/Instrumentation/GCOVProfiling.cpp @@ -118,7 +118,8 @@ private: Function *insertFlush(ArrayRef>); void insertIndirectCounterIncrement(); - std::string mangleName(const DICompileUnit *CU, const char *NewStem); + enum class GCovFileType { GCNO, GCDA }; + std::string mangleName(const DICompileUnit *CU, GCovFileType FileType); GCOVOptions Options; @@ -418,24 +419,40 @@ namespace { } std::string GCOVProfiler::mangleName(const DICompileUnit *CU, - const char *NewStem) { + GCovFileType OutputType) { + bool Notes = OutputType == GCovFileType::GCNO; + if (NamedMDNode *GCov = M->getNamedMetadata("llvm.gcov")) { for (int i = 0, e = GCov->getNumOperands(); i != e; ++i) { MDNode *N = GCov->getOperand(i); - if (N->getNumOperands() != 2) continue; - MDString *GCovFile = dyn_cast(N->getOperand(0)); - MDNode *CompileUnit = dyn_cast(N->getOperand(1)); - if (!GCovFile || !CompileUnit) continue; - if (CompileUnit == CU) { - SmallString<128> Filename = GCovFile->getString(); - sys::path::replace_extension(Filename, NewStem); - return Filename.str(); + bool ThreeElement = N->getNumOperands() == 3; + if (!ThreeElement && N->getNumOperands() != 2) + continue; + if (N->getOperand(ThreeElement ? 2 : 1) != CU) + continue; + + if (ThreeElement) { + // These nodes have no mangling to apply, it's stored mangled in the + // bitcode. + MDString *NotesFile = dyn_cast(N->getOperand(0)); + MDString *DataFile = dyn_cast(N->getOperand(1)); + if (!NotesFile || !DataFile) + continue; + return Notes ? NotesFile->getString() : DataFile->getString(); } + + MDString *GCovFile = dyn_cast(N->getOperand(0)); + if (!GCovFile) + continue; + + SmallString<128> Filename = GCovFile->getString(); + sys::path::replace_extension(Filename, Notes ? "gcno" : "gcda"); + return Filename.str(); } } SmallString<128> Filename = CU->getFilename(); - sys::path::replace_extension(Filename, NewStem); + sys::path::replace_extension(Filename, Notes ? "gcno" : "gcda"); StringRef FName = sys::path::filename(Filename); SmallString<128> CurPath; if (sys::fs::current_path(CurPath)) return FName; @@ -501,7 +518,7 @@ void GCOVProfiler::emitProfileNotes() { continue; std::error_code EC; - raw_fd_ostream out(mangleName(CU, "gcno"), EC, sys::fs::F_None); + raw_fd_ostream out(mangleName(CU, GCovFileType::GCNO), EC, sys::fs::F_None); std::string EdgeDestinations; unsigned FunctionIdent = 0; @@ -849,7 +866,7 @@ Function *GCOVProfiler::insertCounterWriteout( if (CU->getDWOId()) continue; - std::string FilenameGcda = mangleName(CU, "gcda"); + std::string FilenameGcda = mangleName(CU, GCovFileType::GCDA); uint32_t CfgChecksum = FileChecksums.empty() ? 0 : FileChecksums[i]; Builder.CreateCall(StartFile, {Builder.CreateGlobalStringPtr(FilenameGcda), diff --git a/test/Transforms/GCOVProfiling/three-element-mdnode.ll b/test/Transforms/GCOVProfiling/three-element-mdnode.ll new file mode 100644 index 00000000000..132880152b7 --- /dev/null +++ b/test/Transforms/GCOVProfiling/three-element-mdnode.ll @@ -0,0 +1,27 @@ +; RUN: echo '!10 = !{!"%T/aaa.gcno", !"%T/bbb.gcda", !0}' > %t1 +; RUN: cat %s %t1 > %t2 +; RUN: opt -insert-gcov-profiling -S -o %t3 < %t2 +; RUN: grep _Z3foov %T/aaa.gcno +; RUN: grep bbb.gcda %t3 +; RUN: rm %T/aaa.gcno + +define void @_Z3foov() !dbg !5 { +entry: + ret void, !dbg !8 +} + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!9} +!llvm.gcov = !{!10} + +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, producer: "clang version 3.3 (trunk 177323)", isOptimized: false, emissionKind: FullDebug, file: !2, enums: !3, retainedTypes: !3, globals: !3, imports: !3) +!1 = !DIFile(filename: "hello.cc", directory: "/home/nlewycky") +!2 = !DIFile(filename: "hello.cc", directory: "/home/nlewycky") +!3 = !{} +!5 = distinct !DISubprogram(name: "foo", linkageName: "_Z3foov", line: 1, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, unit: !0, scopeLine: 1, file: !1, scope: !1, type: !6, variables: !3) +!6 = !DISubroutineType(types: !7) +!7 = !{null} +!8 = !DILocation(line: 1, scope: !5) + + +!9 = !{i32 1, !"Debug Info Version", i32 3}