Skip to content

[memprof] Use -memprof-default-options to set options during compile time #118874

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Dec 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions compiler-rt/include/sanitizer/memprof_interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,9 @@ void SANITIZER_CDECL __memprof_print_accumulated_stats(void);

/// User-provided default option settings.
///
/// You can provide your own implementation of this function to return a string
/// containing MemProf runtime options (for example,
/// <c>verbosity=1:print_stats=1</c>).
/// You can set these options via the -memprof-runtime-default-options LLVM flag
/// or you can provide your own implementation of this function. See
/// memprof_flags.h for more info.
///
/// \returns Default options string.
const char *SANITIZER_CDECL __memprof_default_options(void);
Expand Down
2 changes: 1 addition & 1 deletion compiler-rt/lib/memprof/memprof_flags.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,5 +89,5 @@ void InitializeFlags() {
} // namespace __memprof

SANITIZER_INTERFACE_WEAK_DEF(const char *, __memprof_default_options, void) {
return "";
return __memprof_default_options_str;
}
16 changes: 9 additions & 7 deletions compiler-rt/lib/memprof/memprof_flags.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,15 @@
#include "sanitizer_common/sanitizer_flag_parser.h"
#include "sanitizer_common/sanitizer_internal_defs.h"

// MemProf flag values can be defined in four ways:
// 1) initialized with default values at startup.
// 2) overriden during compilation of MemProf runtime by providing
// compile definition MEMPROF_DEFAULT_OPTIONS.
// 3) overriden from string returned by user-specified function
// __memprof_default_options().
// 4) overriden from env variable MEMPROF_OPTIONS.
// Default MemProf flags are defined in memprof_flags.inc and sancov_flags.inc.
// These values can be overridded in a number of ways, each option overrides the
// prior one:
// 1) by setting MEMPROF_DEFAULT_OPTIONS during the compilation of the MemProf
// runtime
// 2) by setting the LLVM flag -memprof-runtime-default-options during the
// compilation of your binary
// 3) by overriding the user-specified function __memprof_default_options()
// 4) by setting the environment variable MEMPROF_OPTIONS during runtime

namespace __memprof {

Expand Down
3 changes: 3 additions & 0 deletions compiler-rt/lib/memprof/memprof_interface_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ void __memprof_record_access_range(void const volatile *addr, uptr size);

SANITIZER_INTERFACE_ATTRIBUTE void __memprof_print_accumulated_stats();

SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE extern char
__memprof_default_options_str[1];

SANITIZER_INTERFACE_ATTRIBUTE
const char *__memprof_default_options();

Expand Down
2 changes: 2 additions & 0 deletions compiler-rt/lib/memprof/memprof_rtl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@

#include <time.h>

SANITIZER_WEAK_ATTRIBUTE char __memprof_default_options_str[1];

uptr __memprof_shadow_memory_dynamic_address; // Global interface symbol.

// Allow the user to specify a profile output file via the binary.
Expand Down
2 changes: 1 addition & 1 deletion compiler-rt/lib/memprof/weak_symbols.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
___memprof_default_options __memprof_profile_filename
___memprof_default_options_str ___memprof_default_options __memprof_profile_filename
3 changes: 3 additions & 0 deletions compiler-rt/test/memprof/TestCases/default_options.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
// RUN: %clangxx_memprof -O2 %s -o %t && %run %t 2>&1 | FileCheck %s

// Check that overriding __memprof_default_options() takes precedence over the LLVM flag
// RUN: %clangxx_memprof -O2 %s -o %t-flag -mllvm -memprof-runtime-default-options="verbosity=0 help=0" && %run %t-flag 2>&1 | FileCheck %s

const char *kMemProfDefaultOptions = "verbosity=1 help=1";

extern "C" const char *__memprof_default_options() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the CHECK statement below will need to be updated to check verbosity=1 help=1 to verify the behaviour.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Available flags for MemProfiler: will only output if help=1, which is checked on line 6. So this indeed verifies the expected behavior.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for pointing that out.

Expand Down
16 changes: 16 additions & 0 deletions compiler-rt/test/memprof/TestCases/set_options.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// RUN: %clangxx_memprof %s -o %t-default
// RUN: %run %t-default | FileCheck %s --check-prefix=DEFAULT

// RUN: %clangxx_memprof %s -mllvm -memprof-runtime-default-options="print_text=true,log_path=stdout,atexit=false" -o %t
// RUN: %run %t | FileCheck %s

#include <sanitizer/memprof_interface.h>
#include <stdio.h>

int main() {
printf("Options: \"%s\"\n", __memprof_default_options());
return 0;
}

// DEFAULT: Options: ""
// CHECK: Options: "print_text=true,log_path=stdout,atexit=false"
21 changes: 21 additions & 0 deletions llvm/lib/Transforms/Instrumentation/MemProfiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,11 @@ static cl::opt<bool>
"context in this module's profiles"),
cl::Hidden, cl::init(false));

static cl::opt<std::string>
MemprofRuntimeDefaultOptions("memprof-runtime-default-options",
cl::desc("The default memprof options"),
cl::Hidden, cl::init(""));

extern cl::opt<bool> MemProfReportHintedSizes;

// Instrumentation statistics
Expand Down Expand Up @@ -547,6 +552,20 @@ void createMemprofHistogramFlagVar(Module &M) {
appendToCompilerUsed(M, MemprofHistogramFlag);
}

void createMemprofDefaultOptionsVar(Module &M) {
Constant *OptionsConst = ConstantDataArray::getString(
M.getContext(), MemprofRuntimeDefaultOptions, /*AddNull=*/true);
GlobalVariable *OptionsVar =
new GlobalVariable(M, OptionsConst->getType(), /*isConstant=*/true,
GlobalValue::WeakAnyLinkage, OptionsConst,
"__memprof_default_options_str");
Triple TT(M.getTargetTriple());
if (TT.supportsCOMDAT()) {
OptionsVar->setLinkage(GlobalValue::ExternalLinkage);
OptionsVar->setComdat(M.getOrInsertComdat(OptionsVar->getName()));
}
}

bool ModuleMemProfiler::instrumentModule(Module &M) {

// Create a module constructor.
Expand All @@ -566,6 +585,8 @@ bool ModuleMemProfiler::instrumentModule(Module &M) {

createMemprofHistogramFlagVar(M);

createMemprofDefaultOptionsVar(M);

return true;
}

Expand Down
11 changes: 11 additions & 0 deletions llvm/test/Instrumentation/HeapProfiler/memprof-options.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
; RUN: opt < %s -mtriple=x86_64-unknown-linux -passes='function(memprof),memprof-module' -S | FileCheck %s --check-prefixes=CHECK,EMPTY
; RUN: opt < %s -mtriple=x86_64-unknown-linux -passes='function(memprof),memprof-module' -S -memprof-runtime-default-options="verbose=1" | FileCheck %s --check-prefixes=CHECK,VERBOSE

define i32 @main() {
entry:
ret i32 0
}

; CHECK: $__memprof_default_options_str = comdat any
; EMPTY: @__memprof_default_options_str = constant [1 x i8] zeroinitializer, comdat
; VERBOSE: @__memprof_default_options_str = constant [10 x i8] c"verbose=1\00", comdat
Loading