The attached patch determines what path prefix gcc would use for gcov
coverage data files and puts is in a cc1 flag -coverage-dir which is
threaded into codegen who finally plops it in a metadata node.
The point of putting it in metadata is to allow us to produce a .bc
file and still get the same behaviour as when we go straight to .o
file, and this also will work when we merge .bc files and then run the
-insert-gcov-profiling pass.
It's a small patch. Please review!
Nick
Index: include/clang/Frontend/CodeGenOptions.h
===================================================================
--- include/clang/Frontend/CodeGenOptions.h (revision 130833)
+++ include/clang/Frontend/CodeGenOptions.h (working copy)
@@ -95,6 +95,9 @@
/// The code model to use (-mcmodel).
std::string CodeModel;
+ /// The directory in which to place coverage data files.
+ std::string CoverageDir;
+
/// Enable additional debugging information.
std::string DebugPass;
Index: include/clang/Driver/CC1Options.td
===================================================================
--- include/clang/Driver/CC1Options.td (revision 130833)
+++ include/clang/Driver/CC1Options.td (working copy)
@@ -140,6 +140,9 @@
HelpText<"Emit a gcov coverage notes file when compiling.">;
def femit_coverage_data: Flag<"-femit-coverage-data">,
HelpText<"Instrument the program to emit gcov coverage data when run.">;
+def coverage_dir : Separate<"-coverage-dir">,
+ HelpText<"Emit coverage data to this directory.">;
+def coverage_dir_EQ : Joined<"-coverage-dir=">, Alias<coverage_dir>;
def relaxed_aliasing : Flag<"-relaxed-aliasing">,
HelpText<"Turn off Type Based Alias Analysis">;
def masm_verbose : Flag<"-masm-verbose">,
Index: lib/Frontend/CompilerInvocation.cpp
===================================================================
--- lib/Frontend/CompilerInvocation.cpp (revision 130833)
+++ lib/Frontend/CompilerInvocation.cpp (working copy)
@@ -974,6 +974,7 @@
Opts.InstrumentForProfiling = Args.hasArg(OPT_pg);
Opts.EmitGcovArcs = Args.hasArg(OPT_femit_coverage_data);
Opts.EmitGcovNotes = Args.hasArg(OPT_femit_coverage_notes);
+ Opts.CoverageDir = Args.getLastArgValue(OPT_coverage_dir);
if (Arg *A = Args.getLastArg(OPT_fobjc_dispatch_method_EQ)) {
llvm::StringRef Name = A->getValue(Args);
Index: lib/Driver/Tools.cpp
===================================================================
--- lib/Driver/Tools.cpp (revision 130833)
+++ lib/Driver/Tools.cpp (working copy)
@@ -1303,6 +1303,17 @@
Args.hasArg(options::OPT_coverage))
CmdArgs.push_back("-femit-coverage-data");
+ if (C.getArgs().hasArg(options::OPT_c)) {
+ if (Output.isFilename()) {
+ llvm::StringRef CoverageDir =
+ llvm::sys::path::parent_path(Output.getFilename());
+ if (!CoverageDir.empty()) {
+ CmdArgs.push_back("-coverage-dir");
+ CmdArgs.push_back(Args.MakeArgString(CoverageDir));
+ }
+ }
+ }
+
Args.AddLastArg(CmdArgs, options::OPT_nostdinc);
Args.AddLastArg(CmdArgs, options::OPT_nostdincxx);
Args.AddLastArg(CmdArgs, options::OPT_nobuiltininc);
Index: lib/CodeGen/CodeGenModule.h
===================================================================
--- lib/CodeGen/CodeGenModule.h (revision 130833)
+++ lib/CodeGen/CodeGenModule.h (working copy)
@@ -735,6 +735,10 @@
void EmitDeclMetadata();
+ /// EmitCoverageDir - Emit the llvm.gcov metadata used to tell LLVM where
+ /// to emit the .gcno and .gcda files in a way that persists in .bc files.
+ void EmitCoverageDir();
+
/// MayDeferGeneration - Determine if the given decl can be emitted
/// lazily; this is only relevant for definitions. The given decl
/// must be either a function or var decl.
Index: lib/CodeGen/CodeGenModule.cpp
===================================================================
--- lib/CodeGen/CodeGenModule.cpp (revision 130833)
+++ lib/CodeGen/CodeGenModule.cpp (working copy)
@@ -132,6 +132,9 @@
if (getCodeGenOpts().EmitDeclMetadata)
EmitDeclMetadata();
+
+ if (getCodeGenOpts().EmitGcovArcs || getCodeGenOpts().EmitGcovNotes)
+ EmitCoverageDir();
}
void CodeGenModule::UpdateCompletedType(const TagDecl *TD) {
@@ -2216,6 +2219,23 @@
}
}
+void CodeGenModule::EmitCoverageDir() {
+ if (!getCodeGenOpts().CoverageDir.empty()) {
+ if (llvm::NamedMDNode *CUNode = TheModule.getNamedMetadata("llvm.dbg.cu")) {
+ llvm::NamedMDNode *GCov = TheModule.getOrInsertNamedMetadata("llvm.gcov");
+ llvm::LLVMContext &Ctx = TheModule.getContext();
+ llvm::MDString *CoverageDir =
+ llvm::MDString::get(Ctx, getCodeGenOpts().CoverageDir);
+ for (int i = 0, e = CUNode->getNumOperands(); i != e; ++i) {
+ llvm::MDNode *CU = CUNode->getOperand(i);
+ llvm::Value *node[] = { CoverageDir, CU };
+ llvm::MDNode *N = llvm::MDNode::get(Ctx, node);
+ GCov->addOperand(N);
+ }
+ }
+ }
+}
+
///@name Custom Runtime Function Interfaces
///@{
//
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits