[compiler-rt] 0949f96 - [MemProf] Pass down memory profile name with optional path from clang

Teresa Johnson via llvm-commits llvm-commits at lists.llvm.org
Sun Nov 1 17:38:59 PST 2020


Author: Teresa Johnson
Date: 2020-11-01T17:38:23-08:00
New Revision: 0949f96dc6521be80ebb8ebc1e1c506165c22aac

URL: https://github.com/llvm/llvm-project/commit/0949f96dc6521be80ebb8ebc1e1c506165c22aac
DIFF: https://github.com/llvm/llvm-project/commit/0949f96dc6521be80ebb8ebc1e1c506165c22aac.diff

LOG: [MemProf] Pass down memory profile name with optional path from clang

Similar to -fprofile-generate=, add -fmemory-profile= which takes a
directory path. This is passed down to LLVM via a new module flag
metadata. LLVM in turn provides this name to the runtime via the new
__memprof_profile_filename variable.

Additionally, always pass a default filename (in $cwd if a directory
name is not specified vi the = form of the option). This is also
consistent with the behavior of the PGO instrumentation. Since the
memory profiles will generally be fairly large, it doesn't make sense to
dump them to stderr. Also, importantly, the memory profiles will
eventually be dumped in a compact binary format, which is another reason
why it does not make sense to send these to stderr by default.

Change the existing memprof tests to specify log_path=stderr when that
was being relied on.

Depends on D89086.

Differential Revision: https://reviews.llvm.org/D89087

Added: 
    clang/test/CodeGen/memory-profile-filename.c
    llvm/test/Instrumentation/HeapProfiler/filename.ll

Modified: 
    clang/include/clang/Basic/CodeGenOptions.def
    clang/include/clang/Basic/CodeGenOptions.h
    clang/include/clang/Driver/Options.td
    clang/lib/CodeGen/BackendUtil.cpp
    clang/lib/CodeGen/CodeGenModule.cpp
    clang/lib/Driver/SanitizerArgs.cpp
    clang/lib/Driver/ToolChains/Clang.cpp
    clang/lib/Frontend/CompilerInvocation.cpp
    clang/test/Driver/fmemprof.cpp
    compiler-rt/test/memprof/TestCases/atexit_stats.cpp
    compiler-rt/test/memprof/TestCases/dump_process_map.cpp
    compiler-rt/test/memprof/TestCases/log_path_test.cpp
    compiler-rt/test/memprof/TestCases/malloc-size-too-big.cpp
    compiler-rt/test/memprof/TestCases/mem_info_cache_entries.cpp
    compiler-rt/test/memprof/TestCases/print_miss_rate.cpp
    compiler-rt/test/memprof/TestCases/stress_dtls.c
    compiler-rt/test/memprof/TestCases/test_malloc_load_store.c
    compiler-rt/test/memprof/TestCases/test_memintrin.cpp
    compiler-rt/test/memprof/TestCases/test_new_load_store.cpp
    compiler-rt/test/memprof/TestCases/test_terse.cpp
    compiler-rt/test/memprof/TestCases/unaligned_loads_and_stores.cpp
    llvm/lib/Transforms/Instrumentation/MemProfiler.cpp

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Basic/CodeGenOptions.def b/clang/include/clang/Basic/CodeGenOptions.def
index f5222b50fc7b..7cd80aa806db 100644
--- a/clang/include/clang/Basic/CodeGenOptions.def
+++ b/clang/include/clang/Basic/CodeGenOptions.def
@@ -151,7 +151,6 @@ CODEGENOPT(IncrementalLinkerCompatible, 1, 0) ///< Emit an object file which can
                                               ///< linker.
 CODEGENOPT(MergeAllConstants , 1, 1) ///< Merge identical constants.
 CODEGENOPT(MergeFunctions    , 1, 0) ///< Set when -fmerge-functions is enabled.
-CODEGENOPT(MemProf           , 1, 0) ///< Set when -fmemory-profile is enabled.
 CODEGENOPT(MSVolatile        , 1, 0) ///< Set when /volatile:ms is enabled.
 CODEGENOPT(NoCommon          , 1, 0) ///< Set when -fno-common or C++ is enabled.
 CODEGENOPT(NoDwarfDirectoryAsm , 1, 0) ///< Set when -fno-dwarf-directory-asm is

diff  --git a/clang/include/clang/Basic/CodeGenOptions.h b/clang/include/clang/Basic/CodeGenOptions.h
index 764d0a17cb72..6452d2bb25f6 100644
--- a/clang/include/clang/Basic/CodeGenOptions.h
+++ b/clang/include/clang/Basic/CodeGenOptions.h
@@ -231,6 +231,9 @@ class CodeGenOptions : public CodeGenOptionsBase {
   /// Name of the profile file to use with -fprofile-sample-use.
   std::string SampleProfileFile;
 
+  /// Name of the profile file to use as output for with -fmemory-profile.
+  std::string MemoryProfileOutput;
+
   /// Name of the profile file to use as input for -fprofile-instr-use
   std::string ProfileInstrumentUsePath;
 

diff  --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 0f7440896cb4..165baf06cbb2 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -1017,6 +1017,9 @@ def fsymbol_partition_EQ : Joined<["-"], "fsymbol-partition=">, Group<f_Group>,
   Flags<[CC1Option]>;
 
 defm memory_profile : OptInFFlag<"memory-profile", "Enable", "Disable", " heap memory profiling">;
+def fmemory_profile_EQ : Joined<["-"], "fmemory-profile=">,
+    Group<f_Group>, Flags<[CC1Option]>, MetaVarName<"<directory>">,
+    HelpText<"Enable heap memory profiling and dump results into <directory>">;
 
 // Begin sanitizer flags. These should all be core options exposed in all driver
 // modes.

diff  --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp
index e693d6d05464..1c1068135bb2 100644
--- a/clang/lib/CodeGen/BackendUtil.cpp
+++ b/clang/lib/CodeGen/BackendUtil.cpp
@@ -687,7 +687,7 @@ void EmitAssemblyHelper::CreatePasses(legacy::PassManager &MPM,
   if (LangOpts.Coroutines)
     addCoroutinePassesToExtensionPoints(PMBuilder);
 
-  if (CodeGenOpts.MemProf) {
+  if (!CodeGenOpts.MemoryProfileOutput.empty()) {
     PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast,
                            addMemProfilerPasses);
     PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
@@ -1421,7 +1421,7 @@ void EmitAssemblyHelper::EmitAssemblyWithNewPassManager(
     if (CodeGenOpts.UniqueInternalLinkageNames)
       MPM.addPass(UniqueInternalLinkageNamesPass());
 
-    if (CodeGenOpts.MemProf) {
+    if (!CodeGenOpts.MemoryProfileOutput.empty()) {
       MPM.addPass(createModuleToFunctionPassAdaptor(MemProfilerPass()));
       MPM.addPass(ModuleMemProfilerPass());
     }

diff  --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 2a7fb4ff88ac..66a3c57b9112 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -607,6 +607,13 @@ void CodeGenModule::Release() {
                               !LangOpts.isSignReturnAddressWithAKey());
   }
 
+  if (!CodeGenOpts.MemoryProfileOutput.empty()) {
+    llvm::LLVMContext &Ctx = TheModule.getContext();
+    getModule().addModuleFlag(
+        llvm::Module::Error, "MemProfProfileFilename",
+        llvm::MDString::get(Ctx, CodeGenOpts.MemoryProfileOutput));
+  }
+
   if (LangOpts.CUDAIsDevice && getTriple().isNVPTX()) {
     // Indicate whether __nvvm_reflect should be configured to flush denormal
     // floating point values to 0.  (This corresponds to its "__CUDA_FTZ"

diff  --git a/clang/lib/Driver/SanitizerArgs.cpp b/clang/lib/Driver/SanitizerArgs.cpp
index 68ae25e9cc20..5c275353b679 100644
--- a/clang/lib/Driver/SanitizerArgs.cpp
+++ b/clang/lib/Driver/SanitizerArgs.cpp
@@ -868,6 +868,7 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC,
                     D.CCCIsCXX();
 
   NeedsMemProfRt = Args.hasFlag(options::OPT_fmemory_profile,
+                                options::OPT_fmemory_profile_EQ,
                                 options::OPT_fno_memory_profile, false);
 
   // Finally, initialize the set of available and recoverable sanitizers.

diff  --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index a15067b081b7..53d270917ed3 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -4309,9 +4309,12 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
   if (Args.getLastArg(options::OPT_save_temps_EQ))
     Args.AddLastArg(CmdArgs, options::OPT_save_temps_EQ);
 
-  if (Args.hasFlag(options::OPT_fmemory_profile,
-                   options::OPT_fno_memory_profile, false))
-    Args.AddLastArg(CmdArgs, options::OPT_fmemory_profile);
+  auto *MemProfArg = Args.getLastArg(options::OPT_fmemory_profile,
+                                     options::OPT_fmemory_profile_EQ,
+                                     options::OPT_fno_memory_profile);
+  if (MemProfArg &&
+      !MemProfArg->getOption().matches(options::OPT_fno_memory_profile))
+    MemProfArg->render(Args, CmdArgs);
 
   // Embed-bitcode option.
   // Only white-listed flags below are allowed to be embedded.

diff  --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index 22579161b345..3c0ba31527f7 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -1038,7 +1038,15 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
   Opts.ThinLinkBitcodeFile =
       std::string(Args.getLastArgValue(OPT_fthin_link_bitcode_EQ));
 
-  Opts.MemProf = Args.hasArg(OPT_fmemory_profile);
+  // The memory profile runtime appends the pid to make this name more unique.
+  const char *MemProfileBasename = "memprof.profraw";
+  if (Args.hasArg(OPT_fmemory_profile_EQ)) {
+    SmallString<128> Path(
+        std::string(Args.getLastArgValue(OPT_fmemory_profile_EQ)));
+    llvm::sys::path::append(Path, MemProfileBasename);
+    Opts.MemoryProfileOutput = std::string(Path);
+  } else if (Args.hasArg(OPT_fmemory_profile))
+    Opts.MemoryProfileOutput = MemProfileBasename;
 
   Opts.MSVolatile = Args.hasArg(OPT_fms_volatile);
 

diff  --git a/clang/test/CodeGen/memory-profile-filename.c b/clang/test/CodeGen/memory-profile-filename.c
new file mode 100644
index 000000000000..0041aca1cd7a
--- /dev/null
+++ b/clang/test/CodeGen/memory-profile-filename.c
@@ -0,0 +1,12 @@
+// Test that we get the expected module flag metadata for the memory profile
+// filename.
+// RUN: %clang -target x86_64-linux-gnu -S -emit-llvm -o - %s | FileCheck %s --check-prefix=NONE
+// RUN: %clang -target x86_64-linux-gnu -fmemory-profile -S -emit-llvm -o - %s | FileCheck %s --check-prefix=DEFAULTNAME
+// RUN: %clang -target x86_64-linux-gnu -fmemory-profile=/tmp -S -emit-llvm -o - %s | FileCheck %s --check-prefix=CUSTOMNAME
+int main(void) {
+  return 0;
+}
+
+// NONE-NOT: MemProfProfileFilename
+// DEFAULTNAME: !{i32 1, !"MemProfProfileFilename", !"memprof.profraw"}
+// CUSTOMNAME: !{i32 1, !"MemProfProfileFilename", !"/tmp/memprof.profraw"}

diff  --git a/clang/test/Driver/fmemprof.cpp b/clang/test/Driver/fmemprof.cpp
index 69686442d410..8879580a50ba 100644
--- a/clang/test/Driver/fmemprof.cpp
+++ b/clang/test/Driver/fmemprof.cpp
@@ -1,6 +1,10 @@
 // RUN: %clangxx -target x86_64-linux-gnu -fmemory-profile %s -### 2>&1 | FileCheck %s
+// RUN: %clangxx -target x86_64-linux-gnu -fmemory-profile=foo %s -### 2>&1 | FileCheck %s --check-prefix=DIR
 // RUN: %clangxx -target x86_64-linux-gnu -fmemory-profile -fno-memory-profile %s -### 2>&1 | FileCheck %s --check-prefix=OFF
+// RUN: %clangxx -target x86_64-linux-gnu -fmemory-profile=foo -fno-memory-profile %s -### 2>&1 | FileCheck %s --check-prefix=OFF
 // CHECK: "-cc1" {{.*}} "-fmemory-profile"
 // CHECK: ld{{.*}}libclang_rt.memprof{{.*}}libclang_rt.memprof_cxx
+// DIR: "-cc1" {{.*}} "-fmemory-profile=foo"
+// DIR: ld{{.*}}libclang_rt.memprof{{.*}}libclang_rt.memprof_cxx
 // OFF-NOT: "-fmemory-profile"
 // OFF-NOT: libclang_rt.memprof

diff  --git a/compiler-rt/test/memprof/TestCases/atexit_stats.cpp b/compiler-rt/test/memprof/TestCases/atexit_stats.cpp
index 0f21ae34189e..e5b271b41c7f 100644
--- a/compiler-rt/test/memprof/TestCases/atexit_stats.cpp
+++ b/compiler-rt/test/memprof/TestCases/atexit_stats.cpp
@@ -1,8 +1,8 @@
 // Check atexit option.
 
 // RUN: %clangxx_memprof -O0 %s -o %t
-// RUN: %env_memprof_opts=atexit=1 %run %t 2>&1 | FileCheck %s
-// RUN: %env_memprof_opts=atexit=0 %run %t 2>&1 | FileCheck %s --check-prefix=NOATEXIT
+// RUN: %env_memprof_opts=log_path=stderr:atexit=1 %run %t 2>&1 | FileCheck %s
+// RUN: %env_memprof_opts=log_path=stderr:atexit=0 %run %t 2>&1 | FileCheck %s --check-prefix=NOATEXIT
 
 // CHECK: MemProfiler exit stats:
 // CHECK: Stats: {{[0-9]+}}M malloced ({{[0-9]+}}M for overhead) by {{[0-9]+}} calls

diff  --git a/compiler-rt/test/memprof/TestCases/dump_process_map.cpp b/compiler-rt/test/memprof/TestCases/dump_process_map.cpp
index 2b9e98a5af3e..a6adb2f661f4 100644
--- a/compiler-rt/test/memprof/TestCases/dump_process_map.cpp
+++ b/compiler-rt/test/memprof/TestCases/dump_process_map.cpp
@@ -1,8 +1,8 @@
 // Check print_module_map option.
 
 // RUN: %clangxx_memprof -O0 %s -o %t
-// RUN: %env_memprof_opts=print_module_map=1 %run %t 2>&1 | FileCheck %s
-// RUN: %env_memprof_opts=print_module_map=0 %run %t 2>&1 | FileCheck %s --check-prefix=NOMAP
+// RUN: %env_memprof_opts=log_path=stderr:print_module_map=1 %run %t 2>&1 | FileCheck %s
+// RUN: %env_memprof_opts=log_path=stderr:print_module_map=0 %run %t 2>&1 | FileCheck %s --check-prefix=NOMAP
 
 // CHECK: Process memory map follows:
 // CHECK: dump_process_map.cpp.tmp

diff  --git a/compiler-rt/test/memprof/TestCases/log_path_test.cpp b/compiler-rt/test/memprof/TestCases/log_path_test.cpp
index 92d194be707e..298c182be0c8 100644
--- a/compiler-rt/test/memprof/TestCases/log_path_test.cpp
+++ b/compiler-rt/test/memprof/TestCases/log_path_test.cpp
@@ -3,8 +3,8 @@
 //
 // RUN: %clangxx_memprof  %s -o %t
 
-// Regular run.
-// RUN: %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-GOOD --dump-input=always
+// stderr log_path
+// RUN: %env_memprof_opts=log_path=stderr %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-GOOD --dump-input=always
 
 // Good log_path.
 // RUN: rm -f %t.log.*

diff  --git a/compiler-rt/test/memprof/TestCases/malloc-size-too-big.cpp b/compiler-rt/test/memprof/TestCases/malloc-size-too-big.cpp
index 3831d420c376..1bcde5aecc4c 100644
--- a/compiler-rt/test/memprof/TestCases/malloc-size-too-big.cpp
+++ b/compiler-rt/test/memprof/TestCases/malloc-size-too-big.cpp
@@ -1,8 +1,8 @@
 // RUN: %clangxx_memprof -O0 %s -o %t
-// RUN: %env_memprof_opts=allocator_may_return_null=0 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-SUMMARY
-// RUN: %env_memprof_opts=allocator_may_return_null=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-NULL
+// RUN: %env_memprof_opts=log_path=stderr:allocator_may_return_null=0 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-SUMMARY
+// RUN: %env_memprof_opts=log_path=stderr:allocator_may_return_null=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-NULL
 // Test print_summary
-// RUN: %env_memprof_opts=allocator_may_return_null=0:print_summary=0 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-NOSUMMARY
+// RUN: %env_memprof_opts=log_path=stderr:allocator_may_return_null=0:print_summary=0 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-NOSUMMARY
 
 #include <stdio.h>
 #include <stdlib.h>

diff  --git a/compiler-rt/test/memprof/TestCases/mem_info_cache_entries.cpp b/compiler-rt/test/memprof/TestCases/mem_info_cache_entries.cpp
index 54c416b2c3dc..c253855fbf03 100644
--- a/compiler-rt/test/memprof/TestCases/mem_info_cache_entries.cpp
+++ b/compiler-rt/test/memprof/TestCases/mem_info_cache_entries.cpp
@@ -1,6 +1,6 @@
 // Check mem_info_cache_entries option.
 
-// RUN: %clangxx_memprof -O0 %s -o %t && %env_memprof_opts=mem_info_cache_entries=15:print_mem_info_cache_miss_rate=1:print_mem_info_cache_miss_rate_details=1 %run %t 2>&1 | FileCheck %s
+// RUN: %clangxx_memprof -O0 %s -o %t && %env_memprof_opts=log_path=stderr:mem_info_cache_entries=15:print_mem_info_cache_miss_rate=1:print_mem_info_cache_miss_rate_details=1 %run %t 2>&1 | FileCheck %s
 
 // CHECK: Set 14 miss rate: 0 / {{.*}} = 0.00%
 // CHECK-NOT: Set

diff  --git a/compiler-rt/test/memprof/TestCases/print_miss_rate.cpp b/compiler-rt/test/memprof/TestCases/print_miss_rate.cpp
index c319a48f0c56..e32a0de0d913 100644
--- a/compiler-rt/test/memprof/TestCases/print_miss_rate.cpp
+++ b/compiler-rt/test/memprof/TestCases/print_miss_rate.cpp
@@ -2,8 +2,8 @@
 // print_mem_info_cache_miss_rate_details options.
 
 // RUN: %clangxx_memprof -O0 %s -o %t
-// RUN: %env_memprof_opts=print_mem_info_cache_miss_rate=1 %run %t 2>&1 | FileCheck %s
-// RUN: %env_memprof_opts=print_mem_info_cache_miss_rate=1:print_mem_info_cache_miss_rate_details=1 %run %t 2>&1 | FileCheck %s --check-prefix=DETAILS
+// RUN: %env_memprof_opts=log_path=stderr:print_mem_info_cache_miss_rate=1 %run %t 2>&1 | FileCheck %s
+// RUN: %env_memprof_opts=log_path=stderr:print_mem_info_cache_miss_rate=1:print_mem_info_cache_miss_rate_details=1 %run %t 2>&1 | FileCheck %s --check-prefix=DETAILS
 
 // CHECK: Overall miss rate: 0 / {{.*}} = 0.00%
 // DETAILS: Set 0 miss rate: 0 / {{.*}} = 0.00%

diff  --git a/compiler-rt/test/memprof/TestCases/stress_dtls.c b/compiler-rt/test/memprof/TestCases/stress_dtls.c
index c248ebebd99c..bf5a85858572 100644
--- a/compiler-rt/test/memprof/TestCases/stress_dtls.c
+++ b/compiler-rt/test/memprof/TestCases/stress_dtls.c
@@ -7,9 +7,9 @@
 // RUN: %clangxx_memprof %s -ldl -pthread -o %t
 // RUN: %run %t 0 3
 // RUN: %run %t 2 3
-// RUN: %env_memprof_opts=verbosity=2 %run %t 10 2 2>&1 | FileCheck %s
-// RUN: %env_memprof_opts=verbosity=2:intercept_tls_get_addr=1 %run %t 10 2 2>&1 | FileCheck %s
-// RUN: %env_memprof_opts=verbosity=2:intercept_tls_get_addr=0 %run %t 10 2 2>&1 | FileCheck %s --check-prefix=CHECK0
+// RUN: %env_memprof_opts=log_path=stderr:verbosity=2 %run %t 10 2 2>&1 | FileCheck %s
+// RUN: %env_memprof_opts=log_path=stderr:verbosity=2:intercept_tls_get_addr=1 %run %t 10 2 2>&1 | FileCheck %s
+// RUN: %env_memprof_opts=log_path=stderr:verbosity=2:intercept_tls_get_addr=0 %run %t 10 2 2>&1 | FileCheck %s --check-prefix=CHECK0
 // CHECK: __tls_get_addr
 // CHECK: Creating thread 0
 // CHECK: __tls_get_addr

diff  --git a/compiler-rt/test/memprof/TestCases/test_malloc_load_store.c b/compiler-rt/test/memprof/TestCases/test_malloc_load_store.c
index 61c2b420e41a..7db1ad7cb81c 100644
--- a/compiler-rt/test/memprof/TestCases/test_malloc_load_store.c
+++ b/compiler-rt/test/memprof/TestCases/test_malloc_load_store.c
@@ -3,10 +3,10 @@
 // before exit.
 
 // RUN: %clangxx_memprof -O0 %s -o %t
-// RUN: %env_memprof_opts= %run %t 2>&1 | FileCheck %s
+// RUN: %env_memprof_opts=log_path=stderr %run %t 2>&1 | FileCheck %s
 
 // RUN: %clangxx_memprof -DFREE -O0 %s -o %t
-// RUN: %env_memprof_opts= %run %t 2>&1 | FileCheck %s
+// RUN: %env_memprof_opts=log_path=stderr %run %t 2>&1 | FileCheck %s
 
 // This is actually:
 //  Memory allocation stack id = STACKID

diff  --git a/compiler-rt/test/memprof/TestCases/test_memintrin.cpp b/compiler-rt/test/memprof/TestCases/test_memintrin.cpp
index 199aa4a70bce..005bc8725146 100644
--- a/compiler-rt/test/memprof/TestCases/test_memintrin.cpp
+++ b/compiler-rt/test/memprof/TestCases/test_memintrin.cpp
@@ -1,6 +1,6 @@
 // Check profile with calls to memory intrinsics.
 
-// RUN: %clangxx_memprof -O0 %s -o %t && %run %t 2>&1 | FileCheck %s
+// RUN: %clangxx_memprof -O0 %s -o %t && %env_memprof_opts=log_path=stderr %run %t 2>&1 | FileCheck %s
 
 // This is actually:
 //  Memory allocation stack id = STACKIDP

diff  --git a/compiler-rt/test/memprof/TestCases/test_new_load_store.cpp b/compiler-rt/test/memprof/TestCases/test_new_load_store.cpp
index d3cb300a0a30..9ef3313348db 100644
--- a/compiler-rt/test/memprof/TestCases/test_new_load_store.cpp
+++ b/compiler-rt/test/memprof/TestCases/test_new_load_store.cpp
@@ -3,14 +3,14 @@
 // before exit.
 
 // RUN: %clangxx_memprof -O0 %s -o %t
-// RUN: %env_memprof_opts= %run %t 2>&1 | FileCheck %s
+// RUN: %env_memprof_opts=log_path=stderr %run %t 2>&1 | FileCheck %s
 
 // RUN: %clangxx_memprof -DFREE -O0 %s -o %t
-// RUN: %env_memprof_opts= %run %t 2>&1 | FileCheck %s
+// RUN: %env_memprof_opts=log_path=stderr %run %t 2>&1 | FileCheck %s
 
 // Try again with callbacks instead of inline sequences
 // RUN: %clangxx_memprof -mllvm -memprof-use-callbacks -O0 %s -o %t
-// RUN: %env_memprof_opts= %run %t 2>&1 | FileCheck %s
+// RUN: %env_memprof_opts=log_path=stderr %run %t 2>&1 | FileCheck %s
 
 // This is actually:
 //  Memory allocation stack id = STACKID

diff  --git a/compiler-rt/test/memprof/TestCases/test_terse.cpp b/compiler-rt/test/memprof/TestCases/test_terse.cpp
index 750b49e06bf7..4ac0d5e77278 100644
--- a/compiler-rt/test/memprof/TestCases/test_terse.cpp
+++ b/compiler-rt/test/memprof/TestCases/test_terse.cpp
@@ -3,10 +3,10 @@
 // deallocated before exit.
 
 // RUN: %clangxx_memprof -O0 %s -o %t
-// RUN: %env_memprof_opts=print_terse=1 %run %t 2>&1 | FileCheck %s
+// RUN: %env_memprof_opts=log_path=stderr:print_terse=1 %run %t 2>&1 | FileCheck %s
 
 // RUN: %clangxx_memprof -DFREE -O0 %s -o %t
-// RUN: %env_memprof_opts=print_terse=1 %run %t 2>&1 | FileCheck %s
+// RUN: %env_memprof_opts=log_path=stderr:print_terse=1 %run %t 2>&1 | FileCheck %s
 
 // CHECK: MIB:[[STACKID:[0-9]+]]/1/40.00/40/40/20.00/20/20/[[AVELIFETIME:[0-9]+]].00/[[AVELIFETIME]]/[[AVELIFETIME]]/0/0/0/0
 // CHECK: Stack for id [[STACKID]]:

diff  --git a/compiler-rt/test/memprof/TestCases/unaligned_loads_and_stores.cpp b/compiler-rt/test/memprof/TestCases/unaligned_loads_and_stores.cpp
index 1d25ddf3ad2f..c007b4371608 100644
--- a/compiler-rt/test/memprof/TestCases/unaligned_loads_and_stores.cpp
+++ b/compiler-rt/test/memprof/TestCases/unaligned_loads_and_stores.cpp
@@ -1,4 +1,4 @@
-// RUN: %clangxx_memprof -O0 %s -o %t && %run %t 2>&1 | FileCheck %s
+// RUN: %clangxx_memprof -O0 %s -o %t && %env_memprof_opts=log_path=stderr %run %t 2>&1 | FileCheck %s
 
 // This is actually:
 //  Memory allocation stack id = STACKID

diff  --git a/llvm/lib/Transforms/Instrumentation/MemProfiler.cpp b/llvm/lib/Transforms/Instrumentation/MemProfiler.cpp
index 7f2a5ae1a189..32fd11a258fa 100644
--- a/llvm/lib/Transforms/Instrumentation/MemProfiler.cpp
+++ b/llvm/lib/Transforms/Instrumentation/MemProfiler.cpp
@@ -60,6 +60,8 @@ constexpr char MemProfVersionCheckNamePrefix[] =
 constexpr char MemProfShadowMemoryDynamicAddress[] =
     "__memprof_shadow_memory_dynamic_address";
 
+constexpr char MemProfFilenameVar[] = "__memprof_profile_filename";
+
 // Command-line flags.
 
 static cl::opt<bool> ClInsertVersionCheck(
@@ -486,6 +488,26 @@ void MemProfiler::instrumentAddress(Instruction *OrigIns,
   IRB.CreateStore(ShadowValue, ShadowAddr);
 }
 
+// Create the variable for the profile file name.
+void createProfileFileNameVar(Module &M) {
+  const MDString *MemProfFilename =
+      dyn_cast_or_null<MDString>(M.getModuleFlag("MemProfProfileFilename"));
+  if (!MemProfFilename)
+    return;
+  assert(!MemProfFilename->getString().empty() &&
+         "Unexpected MemProfProfileFilename metadata with empty string");
+  Constant *ProfileNameConst = ConstantDataArray::getString(
+      M.getContext(), MemProfFilename->getString(), true);
+  GlobalVariable *ProfileNameVar = new GlobalVariable(
+      M, ProfileNameConst->getType(), /*isConstant=*/true,
+      GlobalValue::WeakAnyLinkage, ProfileNameConst, MemProfFilenameVar);
+  Triple TT(M.getTargetTriple());
+  if (TT.supportsCOMDAT()) {
+    ProfileNameVar->setLinkage(GlobalValue::ExternalLinkage);
+    ProfileNameVar->setComdat(M.getOrInsertComdat(MemProfFilenameVar));
+  }
+}
+
 bool ModuleMemProfiler::instrumentModule(Module &M) {
   // Create a module constructor.
   std::string MemProfVersion = std::to_string(LLVM_MEM_PROFILER_VERSION);
@@ -500,6 +522,8 @@ bool ModuleMemProfiler::instrumentModule(Module &M) {
   const uint64_t Priority = getCtorAndDtorPriority(TargetTriple);
   appendToGlobalCtors(M, MemProfCtorFunction, Priority);
 
+  createProfileFileNameVar(M);
+
   return true;
 }
 

diff  --git a/llvm/test/Instrumentation/HeapProfiler/filename.ll b/llvm/test/Instrumentation/HeapProfiler/filename.ll
new file mode 100644
index 000000000000..f019a9491f0e
--- /dev/null
+++ b/llvm/test/Instrumentation/HeapProfiler/filename.ll
@@ -0,0 +1,15 @@
+; Test to ensure that the filename provided by clang in the module flags
+; metadata results in the expected __memprof_profile_filename insertion.
+
+; RUN: opt < %s -mtriple=x86_64-unknown-linux -memprof -memprof-module -S | FileCheck --check-prefixes=CHECK %s
+
+define i32 @main() {
+entry:
+  ret i32 0
+}
+
+!llvm.module.flags = !{!0}
+!0 = !{i32 1, !"MemProfProfileFilename", !"/tmp/memprof.profraw"}
+
+; CHECK: $__memprof_profile_filename = comdat any
+; CHECK: @__memprof_profile_filename = constant [21 x i8] c"/tmp/memprof.profraw\00", comdat


        


More information about the llvm-commits mailing list