https://github.com/jdoerfert updated https://github.com/llvm/llvm-project/pull/196235
>From 358b5e8d422262551c12a3b02c4832624eb76f07 Mon Sep 17 00:00:00 2001 From: Johannes Doerfert <[email protected]> Date: Wed, 6 May 2026 20:26:11 -0700 Subject: [PATCH] [Instrumentor] Allow multiple config files with different filters To instrument different functions in different ways we allow to provide multiple config files now. Each file will result in one instrumentation run. Multiple files can be passed via command line option or listed in a "summary" file that is passed via command line option (to keep the command length managable). --- .../Instrumentor/InstrumentorStackUsage.cpp | 2 +- .../Instrumentor/InstrumentorUnreachable.cpp | 2 +- .../llvm/Transforms/IPO/Instrumentor.h | 12 +++- .../Transforms/IPO/InstrumentorConfigFile.h | 6 ++ llvm/lib/Transforms/IPO/Instrumentor.cpp | 67 +++++++++++++++---- .../Transforms/IPO/InstrumentorConfigFile.cpp | 37 ++++++++++ .../Instrumentor/alloca_and_function.ll | 40 +++++------ .../Instrumentor/bad_function_regexp.ll | 2 +- .../Instrumentation/Instrumentor/counters.ll | 2 +- .../Instrumentor/function_regex.ll | 2 +- .../Instrumentor/generate_bad_rt.ll | 2 +- .../Instrumentor/generate_rt.ll | 2 +- .../Instrumentor/load_store.ll | 2 +- .../Instrumentor/load_store_args.ll | 2 +- .../Instrumentor/load_store_noreplace.ll | 2 +- .../Instrumentor/multi_config.ll | 56 ++++++++++++++++ .../Instrumentor/multi_config_1.json | 12 ++++ .../Instrumentor/multi_config_2.json | 12 ++++ .../Instrumentor/multi_config_3.json | 12 ++++ .../Instrumentor/multi_config_4.json | 16 +++++ .../Instrumentor/multi_config_paths | 2 + .../Instrumentor/read_config.ll | 2 +- 22 files changed, 248 insertions(+), 46 deletions(-) create mode 100644 llvm/test/Instrumentation/Instrumentor/multi_config.ll create mode 100644 llvm/test/Instrumentation/Instrumentor/multi_config_1.json create mode 100644 llvm/test/Instrumentation/Instrumentor/multi_config_2.json create mode 100644 llvm/test/Instrumentation/Instrumentor/multi_config_3.json create mode 100644 llvm/test/Instrumentation/Instrumentor/multi_config_4.json create mode 100644 llvm/test/Instrumentation/Instrumentor/multi_config_paths diff --git a/clang/test/Instrumentor/InstrumentorStackUsage.cpp b/clang/test/Instrumentor/InstrumentorStackUsage.cpp index ade099764143c..f941a6d470241 100644 --- a/clang/test/Instrumentor/InstrumentorStackUsage.cpp +++ b/clang/test/Instrumentor/InstrumentorStackUsage.cpp @@ -1,6 +1,6 @@ // NOTE: Assertions have been autogenerated by utils/update_test_checks.py // RUN: %clangxx -O0 %S/StackUsageRT.cpp -o %t.StackUsageRT.o -c -// RUN: %clangxx -O0 -mllvm -enable-instrumentor -mllvm -instrumentor-read-config-file=%S/StackUsageRT.json %t.StackUsageRT.o -o %t %s +// RUN: %clangxx -O0 -mllvm -enable-instrumentor -mllvm -instrumentor-read-config-files=%S/StackUsageRT.json %t.StackUsageRT.o -o %t %s // RUN: %t | FileCheck %s static void foobar(int *A, int N) { diff --git a/clang/test/Instrumentor/InstrumentorUnreachable.cpp b/clang/test/Instrumentor/InstrumentorUnreachable.cpp index 5fa0c9b5318ef..310c8c6763d0c 100644 --- a/clang/test/Instrumentor/InstrumentorUnreachable.cpp +++ b/clang/test/Instrumentor/InstrumentorUnreachable.cpp @@ -1,6 +1,6 @@ // NOTE: Assertions have been autogenerated by utils/update_test_checks.py // RUN: %clangxx -O0 %S/UnreachableRT.cpp -o %t.UnreachableRT.o -c -// RUN: %clangxx -O0 -mllvm -enable-instrumentor -mllvm -instrumentor-read-config-file=%S/UnreachableRT.json %t.UnreachableRT.o -o %t %s +// RUN: %clangxx -O0 -mllvm -enable-instrumentor -mllvm -instrumentor-read-config-files=%S/UnreachableRT.json %t.UnreachableRT.o -o %t %s // RUN: not %t 2>&1 | FileCheck %s --check-prefix=FIRST // RUN: not %t arg 2>&1 | FileCheck %s --check-prefix=SECOND diff --git a/llvm/include/llvm/Transforms/IPO/Instrumentor.h b/llvm/include/llvm/Transforms/IPO/Instrumentor.h index ba3ad2498c873..50875f266b205 100644 --- a/llvm/include/llvm/Transforms/IPO/Instrumentor.h +++ b/llvm/include/llvm/Transforms/IPO/Instrumentor.h @@ -348,7 +348,16 @@ struct InstrumentationConfig { virtual ~InstrumentationConfig() {} /// Construct an instrumentation configuration with the base options. - InstrumentationConfig() : SS(StringAllocator) { + InstrumentationConfig() : SS(StringAllocator) {} + + /// Initialize the config to a clean base state without loosing cached values + /// that can be reused across configurations. + virtual void init(InstrumentorIRBuilderTy &IIRB) { + // Clear previous configurations but not the caches. + BaseConfigurationOptions.clear(); + for (auto &Map : IChoices) + Map.clear(); + RuntimePrefix = BaseConfigurationOption::createStringOption( *this, "runtime_prefix", "The runtime API prefix.", "__instrumentor_"); RuntimeStubsFile = BaseConfigurationOption::createStringOption( @@ -371,6 +380,7 @@ struct InstrumentationConfig { *this, "host_enabled", "Instrument non-GPU targets", true); GPUEnabled = BaseConfigurationOption::createBoolOption( *this, "gpu_enabled", "Instrument GPU targets", true); + populate(IIRB); } /// Populate the instrumentation opportunities. diff --git a/llvm/include/llvm/Transforms/IPO/InstrumentorConfigFile.h b/llvm/include/llvm/Transforms/IPO/InstrumentorConfigFile.h index 28efa77d772c4..21c5f72dc34db 100644 --- a/llvm/include/llvm/Transforms/IPO/InstrumentorConfigFile.h +++ b/llvm/include/llvm/Transforms/IPO/InstrumentorConfigFile.h @@ -14,6 +14,7 @@ #define LLVM_TRANSFORMS_IPO_INSTRUMENTOR_CONFIGFILE_H #include "llvm/ADT/StringRef.h" +#include "llvm/IR/LLVMContext.h" #include "llvm/Transforms/IPO/Instrumentor.h" namespace llvm { @@ -27,6 +28,11 @@ void writeConfigToJSON(InstrumentationConfig &IConf, StringRef OutputFile, bool readConfigFromJSON(InstrumentationConfig &IConf, StringRef InputFile, LLVMContext &Ctx, vfs::FileSystem &FS); +/// Read the configuration paths from the file with path \p InputFile into \p +/// Configs. +bool readConfigPathsFile(StringRef InputFile, cl::list<std::string> &Configs, + LLVMContext &Ctx, vfs::FileSystem &FS); + } // end namespace instrumentor } // end namespace llvm diff --git a/llvm/lib/Transforms/IPO/Instrumentor.cpp b/llvm/lib/Transforms/IPO/Instrumentor.cpp index 3862bfbbee9fa..85ab422bb3fef 100644 --- a/llvm/lib/Transforms/IPO/Instrumentor.cpp +++ b/llvm/lib/Transforms/IPO/Instrumentor.cpp @@ -12,6 +12,7 @@ //===----------------------------------------------------------------------===// #include "llvm/Transforms/IPO/Instrumentor.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/Transforms/IPO/InstrumentorConfigFile.h" #include "llvm/Transforms/IPO/InstrumentorStubPrinter.h" @@ -64,17 +65,25 @@ using namespace llvm::instrumentor; namespace { /// The user option to specify an output JSON file to write the configuration. -static cl::opt<std::string> WriteConfigFile( +static cl::opt<std::string> OutputConfigFile( "instrumentor-write-config-file", cl::desc( "Write the instrumentor configuration into the specified JSON file"), cl::init("")); -/// The user option to specify an input JSON file to read the configuration. -static cl::opt<std::string> ReadConfigFile( - "instrumentor-read-config-file", - cl::desc( - "Read the instrumentor configuration from the specified JSON file"), +/// The user option to specify input JSON files to read the configuration from. +static cl::list<std::string> + ConfigFiles("instrumentor-read-config-files", + cl::desc("Read the instrumentor configuration from the " + "specified JSON files (comma separated)"), + cl::ZeroOrMore, cl::CommaSeparated); + +/// The user option to specify an input file to read the configuration file +/// paths from. +static cl::opt<std::string> ConfigPathsFile( + "instrumentor-read-config-paths-file", + cl::desc("Read the instrumentor configuration file " + "paths from the specified file (newline separated)"), cl::init("")); /// Set the debug location, if not set, after changing the insertion point of @@ -132,13 +141,19 @@ class InstrumentorImpl final { /// Construct an instrumentor implementation using the configuration \p IConf. InstrumentorImpl(InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB, Module &M) - : IConf(IConf), M(M), IIRB(IIRB) { - IConf.populate(IIRB); - } + : IConf(IConf), M(M), IIRB(IIRB) {} /// Instrument the module, public entry point. bool instrument(); + // Reset the sate to allow reuse of the instrumentor with a different + // configuration. + void clear() { + InstChoicesPRE.clear(); + InstChoicesPOST.clear(); + ParsedFunctionRegex = Regex(); + } + private: /// Indicate if the module should be instrumented based on the target. bool shouldInstrumentTarget(); @@ -326,15 +341,39 @@ InstrumentorPass::InstrumentorPass(IntrusiveRefCntPtr<vfs::FileSystem> FS, PreservedAnalyses InstrumentorPass::run(Module &M, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB, bool ReadConfig) { + bool Changed = false; InstrumentorImpl Impl(IConf, IIRB, M); - if (ReadConfig && !readConfigFromJSON(IConf, ReadConfigFile, IIRB.Ctx, *FS)) - return PreservedAnalyses::all(); - writeConfigToJSON(IConf, WriteConfigFile, IIRB.Ctx); + // If this is a configuration driven run, iterate over all configurations + // provided by the user, if not, use the config as is and run the instrumentor + // once. + if (ReadConfig) + readConfigPathsFile(ConfigPathsFile, ConfigFiles, IIRB.Ctx, *FS); + + bool MultipleConfigs = ConfigFiles.size() > 1; + unsigned Idx = 0; + do { + std::string ConfigFile = + ReadConfig && !ConfigFiles.empty() ? ConfigFiles[Idx] : ""; + + // Initialize the config to the base state but keep the caches around. + Impl.clear(); + IConf.init(IIRB); + + if (!readConfigFromJSON(IConf, ConfigFile, IIRB.Ctx, *FS)) + continue; + + auto AddSuffix = [&](std::string S) { + return MultipleConfigs ? S + "." + std::to_string(Idx) : S; + }; + + writeConfigToJSON(IConf, AddSuffix(OutputConfigFile), IIRB.Ctx); + + printRuntimeStub(IConf, IConf.RuntimeStubsFile->getString(), IIRB.Ctx); - printRuntimeStub(IConf, IConf.RuntimeStubsFile->getString(), IIRB.Ctx); + Changed |= Impl.instrument(); + } while (++Idx < ConfigFiles.size()); - bool Changed = Impl.instrument(); if (!Changed) return PreservedAnalyses::all(); return PreservedAnalyses::none(); diff --git a/llvm/lib/Transforms/IPO/InstrumentorConfigFile.cpp b/llvm/lib/Transforms/IPO/InstrumentorConfigFile.cpp index 7ee800a5c96a0..cfe4a474a3921 100644 --- a/llvm/lib/Transforms/IPO/InstrumentorConfigFile.cpp +++ b/llvm/lib/Transforms/IPO/InstrumentorConfigFile.cpp @@ -16,9 +16,11 @@ #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" #include "llvm/IR/DiagnosticInfo.h" +#include "llvm/IR/LLVMContext.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/JSON.h" #include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/Path.h" #include "llvm/Support/StringSaver.h" #include "llvm/Support/VirtualFileSystem.h" @@ -232,5 +234,40 @@ bool readConfigFromJSON(InstrumentationConfig &IConf, StringRef InputFile, return true; } +bool readConfigPathsFile(StringRef InputFile, cl::list<std::string> &Configs, + LLVMContext &Ctx, vfs::FileSystem &FS) { + if (InputFile.empty()) + return true; + + auto BufferOrErr = setupMemoryBuffer(InputFile, FS); + if (Error E = BufferOrErr.takeError()) { + Ctx.diagnose(DiagnosticInfoInstrumentation( + Twine("failed to open instrumentor configuration paths file for " + "reading: ") + + toString(std::move(E)), + DS_Warning)); + return false; + } + + StringRef InputFilePath(sys::path::parent_path(InputFile)); + + auto Buffer = std::move(BufferOrErr.get()); + StringRef Content = Buffer->getBuffer(); + StringRef EOL = Content.detectEOL(); + do { + auto [LHS, RHS] = Content.split(EOL); + std::string ConfigPath = LHS.trim().str(); + if (!sys::path::is_absolute(ConfigPath)) { + SmallString<128> InputFilePathStringVec(InputFilePath); + sys::path::append(InputFilePathStringVec, ConfigPath); + ConfigPath = InputFilePathStringVec.c_str(); + } + Configs.push_back(ConfigPath); + Content = RHS.trim(); + } while (!Content.empty()); + + return true; +} + } // end namespace instrumentor } // end namespace llvm diff --git a/llvm/test/Instrumentation/Instrumentor/alloca_and_function.ll b/llvm/test/Instrumentation/Instrumentor/alloca_and_function.ll index e65562bfe8caf..fa5564003c94d 100644 --- a/llvm/test/Instrumentation/Instrumentor/alloca_and_function.ll +++ b/llvm/test/Instrumentation/Instrumentor/alloca_and_function.ll @@ -23,31 +23,31 @@ entry: ; CHECK-LABEL: define float @foo( ; CHECK-SAME: i16 [[A:%.*]], float [[B:%.*]]) { ; CHECK-NEXT: [[ENTRY:.*:]] -; CHECK-NEXT: [[TMP7:%.*]] = alloca <{ i32, i32, [6 x i8], i16, i32, i32, [4 x i8], float }>, align 8 -; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 8 [[TMP7]], ptr @__instrumentor_value_pack, i64 32, i1 false) -; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds nuw <{ i32, i32, [6 x i8], i16, i32, i32, [4 x i8], float }>, ptr [[TMP7]], i32 0, i32 3 +; CHECK-NEXT: [[TMP0:%.*]] = alloca <{ i32, i32, [6 x i8], i16, i32, i32, [4 x i8], float }>, align 8 +; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 8 [[TMP0]], ptr @__instrumentor_value_pack, i64 32, i1 false) +; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds nuw <{ i32, i32, [6 x i8], i16, i32, i32, [4 x i8], float }>, ptr [[TMP0]], i32 0, i32 3 ; CHECK-NEXT: store i16 [[A]], ptr [[TMP2]], align 2 -; CHECK-NEXT: [[TMP9:%.*]] = getelementptr inbounds nuw <{ i32, i32, [6 x i8], i16, i32, i32, [4 x i8], float }>, ptr [[TMP7]], i32 0, i32 7 -; CHECK-NEXT: store float [[B]], ptr [[TMP9]], align 4 -; CHECK-NEXT: call void @__instrumentor_pre_function(ptr @foo, ptr @__instrumentor_.str, i32 2, ptr [[TMP7]], i8 0, i32 3) #[[ATTR1:[0-9]+]] -; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds i8, ptr [[TMP7]], i32 14 +; CHECK-NEXT: [[TMP14:%.*]] = getelementptr inbounds nuw <{ i32, i32, [6 x i8], i16, i32, i32, [4 x i8], float }>, ptr [[TMP0]], i32 0, i32 7 +; CHECK-NEXT: store float [[B]], ptr [[TMP14]], align 4 +; CHECK-NEXT: call void @__instrumentor_pre_function(ptr @foo, ptr @__instrumentor_.str, i32 2, ptr [[TMP0]], i8 0, i32 3) #[[ATTR1:[0-9]+]] +; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds i8, ptr [[TMP0]], i32 14 ; CHECK-NEXT: [[TMP4:%.*]] = load i16, ptr [[TMP3]], align 2 -; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds i8, ptr [[TMP7]], i32 28 +; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds i8, ptr [[TMP0]], i32 28 ; CHECK-NEXT: [[TMP6:%.*]] = load float, ptr [[TMP5]], align 4 -; CHECK-NEXT: [[TMP0:%.*]] = call i64 @__instrumentor_pre_alloca(i64 2, i64 16, i32 1) #[[ATTR1]] -; CHECK-NEXT: [[TMP1:%.*]] = alloca i8, i64 [[TMP0]], align 16 -; CHECK-NEXT: [[TMP13:%.*]] = call ptr @__instrumentor_post_alloca(ptr [[TMP1]], i64 2, i64 16, i32 -1) #[[ATTR1]] +; CHECK-NEXT: [[TMP7:%.*]] = call i64 @__instrumentor_pre_alloca(i64 2, i64 16, i32 1) #[[ATTR1]] +; CHECK-NEXT: [[TMP8:%.*]] = alloca i8, i64 [[TMP7]], align 16 +; CHECK-NEXT: [[TMP9:%.*]] = call ptr @__instrumentor_post_alloca(ptr [[TMP8]], i64 2, i64 16, i32 -1) #[[ATTR1]] ; CHECK-NEXT: [[TMP10:%.*]] = zext i16 [[TMP4]] to i64 -; CHECK-NEXT: [[TMP14:%.*]] = call ptr @__instrumentor_pre_store(ptr [[TMP13]], i32 0, i64 [[TMP10]], i64 2, i64 2, i32 12, i32 0, i8 1, i8 0, i32 2) #[[ATTR1]] -; CHECK-NEXT: store i16 [[TMP4]], ptr [[TMP14]], align 2 -; CHECK-NEXT: call void @__instrumentor_post_store(ptr [[TMP13]], i32 0, i64 [[TMP10]], i64 2, i64 2, i32 12, i32 0, i8 1, i8 0, i32 -2) #[[ATTR1]] -; CHECK-NEXT: call void @use(ptr [[TMP13]]) -; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 8 [[TMP7]], ptr @__instrumentor_value_pack, i64 32, i1 false) -; CHECK-NEXT: [[TMP12:%.*]] = getelementptr inbounds nuw <{ i32, i32, [6 x i8], i16, i32, i32, [4 x i8], float }>, ptr [[TMP7]], i32 0, i32 3 +; CHECK-NEXT: [[TMP11:%.*]] = call ptr @__instrumentor_pre_store(ptr [[TMP9]], i32 0, i64 [[TMP10]], i64 2, i64 2, i32 12, i32 0, i8 1, i8 0, i32 2) #[[ATTR1]] +; CHECK-NEXT: store i16 [[TMP4]], ptr [[TMP11]], align 2 +; CHECK-NEXT: call void @__instrumentor_post_store(ptr [[TMP9]], i32 0, i64 [[TMP10]], i64 2, i64 2, i32 12, i32 0, i8 1, i8 0, i32 -2) #[[ATTR1]] +; CHECK-NEXT: call void @use(ptr [[TMP9]]) +; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 8 [[TMP0]], ptr @__instrumentor_value_pack, i64 32, i1 false) +; CHECK-NEXT: [[TMP12:%.*]] = getelementptr inbounds nuw <{ i32, i32, [6 x i8], i16, i32, i32, [4 x i8], float }>, ptr [[TMP0]], i32 0, i32 3 ; CHECK-NEXT: store i16 [[A]], ptr [[TMP12]], align 2 -; CHECK-NEXT: [[TMP11:%.*]] = getelementptr inbounds nuw <{ i32, i32, [6 x i8], i16, i32, i32, [4 x i8], float }>, ptr [[TMP7]], i32 0, i32 7 -; CHECK-NEXT: store float [[B]], ptr [[TMP11]], align 4 -; CHECK-NEXT: call void @__instrumentor_post_function(ptr @foo, ptr @__instrumentor_.str, i32 2, ptr [[TMP7]], i8 0, i32 -4) #[[ATTR1]] +; CHECK-NEXT: [[TMP13:%.*]] = getelementptr inbounds nuw <{ i32, i32, [6 x i8], i16, i32, i32, [4 x i8], float }>, ptr [[TMP0]], i32 0, i32 7 +; CHECK-NEXT: store float [[B]], ptr [[TMP13]], align 4 +; CHECK-NEXT: call void @__instrumentor_post_function(ptr @foo, ptr @__instrumentor_.str, i32 2, ptr [[TMP0]], i8 0, i32 -4) #[[ATTR1]] ; CHECK-NEXT: ret float [[TMP6]] ; ;. diff --git a/llvm/test/Instrumentation/Instrumentor/bad_function_regexp.ll b/llvm/test/Instrumentation/Instrumentor/bad_function_regexp.ll index 8ee73531a3d69..ffcbca33a346e 100644 --- a/llvm/test/Instrumentation/Instrumentor/bad_function_regexp.ll +++ b/llvm/test/Instrumentation/Instrumentor/bad_function_regexp.ll @@ -1,4 +1,4 @@ -; RUN: not opt < %s -passes=instrumentor -instrumentor-read-config-file=%S/bad_function_regex.json -S 2>&1 | FileCheck %s +; RUN: not opt < %s -passes=instrumentor -instrumentor-read-config-files=%S/bad_function_regex.json -S 2>&1 | FileCheck %s ; CHECK: error: failed to parse target regex: repetition-operator operand invalid diff --git a/llvm/test/Instrumentation/Instrumentor/counters.ll b/llvm/test/Instrumentation/Instrumentor/counters.ll index 81512b6a054d6..47b8e2a5d4d3a 100644 --- a/llvm/test/Instrumentation/Instrumentor/counters.ll +++ b/llvm/test/Instrumentation/Instrumentor/counters.ll @@ -1,5 +1,5 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5 -; RUN: opt < %s -passes=instrumentor -instrumentor-read-config-file=%S/counters_config.json -S | FileCheck %s +; RUN: opt < %s -passes=instrumentor -instrumentor-read-config-files=%S/counters_config.json -S | FileCheck %s target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" diff --git a/llvm/test/Instrumentation/Instrumentor/function_regex.ll b/llvm/test/Instrumentation/Instrumentor/function_regex.ll index 29e28611aa114..64ee4340b45dc 100644 --- a/llvm/test/Instrumentation/Instrumentor/function_regex.ll +++ b/llvm/test/Instrumentation/Instrumentor/function_regex.ll @@ -1,5 +1,5 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py -; RUN: opt < %s -passes=instrumentor -instrumentor-read-config-file=%S/function_regex.json -S | FileCheck %s +; RUN: opt < %s -passes=instrumentor -instrumentor-read-config-files=%S/function_regex.json -S | FileCheck %s target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" diff --git a/llvm/test/Instrumentation/Instrumentor/generate_bad_rt.ll b/llvm/test/Instrumentation/Instrumentor/generate_bad_rt.ll index 11b080b8b2e97..2c3a853055d2a 100644 --- a/llvm/test/Instrumentation/Instrumentor/generate_bad_rt.ll +++ b/llvm/test/Instrumentation/Instrumentor/generate_bad_rt.ll @@ -1,3 +1,3 @@ -; RUN: not opt < %s -passes=instrumentor -instrumentor-read-config-file=%S/bad_rt_config.json 2>&1 | FileCheck %s --ignore-case +; RUN: not opt < %s -passes=instrumentor -instrumentor-read-config-files=%S/bad_rt_config.json 2>&1 | FileCheck %s --ignore-case ; CHECK: error: failed to open instrumentor stub runtime file for writing: Is a directory diff --git a/llvm/test/Instrumentation/Instrumentor/generate_rt.ll b/llvm/test/Instrumentation/Instrumentor/generate_rt.ll index b879437d79b8a..3fe64c15bf353 100644 --- a/llvm/test/Instrumentation/Instrumentor/generate_rt.ll +++ b/llvm/test/Instrumentation/Instrumentor/generate_rt.ll @@ -1,2 +1,2 @@ -; RUN: opt < %s -passes=instrumentor -instrumentor-read-config-file=%S/rt_config.json -S +; RUN: opt < %s -passes=instrumentor -instrumentor-read-config-files=%S/rt_config.json -S ; RUN: diff -b rt.c %S/default_rt diff --git a/llvm/test/Instrumentation/Instrumentor/load_store.ll b/llvm/test/Instrumentation/Instrumentor/load_store.ll index 43fb2d593d75c..6cfdaaaa85cb5 100644 --- a/llvm/test/Instrumentation/Instrumentor/load_store.ll +++ b/llvm/test/Instrumentation/Instrumentor/load_store.ll @@ -1,5 +1,5 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5 -; RUN: opt < %s -passes=instrumentor -instrumentor-read-config-file=%S/load_store_config.json -S | FileCheck %s +; RUN: opt < %s -passes=instrumentor -instrumentor-read-config-files=%S/load_store_config.json -S | FileCheck %s target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128" diff --git a/llvm/test/Instrumentation/Instrumentor/load_store_args.ll b/llvm/test/Instrumentation/Instrumentor/load_store_args.ll index ad4c1b8d0fc70..aeda9bad5c30f 100644 --- a/llvm/test/Instrumentation/Instrumentor/load_store_args.ll +++ b/llvm/test/Instrumentation/Instrumentor/load_store_args.ll @@ -1,5 +1,5 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5 -; RUN: opt < %s -passes=instrumentor -instrumentor-read-config-file=%S/load_store_config.json -S | FileCheck %s +; RUN: opt < %s -passes=instrumentor -instrumentor-read-config-files=%S/load_store_config.json -S | FileCheck %s target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128" diff --git a/llvm/test/Instrumentation/Instrumentor/load_store_noreplace.ll b/llvm/test/Instrumentation/Instrumentor/load_store_noreplace.ll index 31ca22ddefca9..e00233b0cfcd0 100644 --- a/llvm/test/Instrumentation/Instrumentor/load_store_noreplace.ll +++ b/llvm/test/Instrumentation/Instrumentor/load_store_noreplace.ll @@ -1,5 +1,5 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5 -; RUN: opt < %s -passes=instrumentor -instrumentor-read-config-file=%S/load_store_noreplace_config.json -S | FileCheck %s +; RUN: opt < %s -passes=instrumentor -instrumentor-read-config-files=%S/load_store_noreplace_config.json -S | FileCheck %s target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128" diff --git a/llvm/test/Instrumentation/Instrumentor/multi_config.ll b/llvm/test/Instrumentation/Instrumentor/multi_config.ll new file mode 100644 index 0000000000000..445e57ff44b5d --- /dev/null +++ b/llvm/test/Instrumentation/Instrumentor/multi_config.ll @@ -0,0 +1,56 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt < %s -passes=instrumentor -instrumentor-read-config-files=%S/multi_config_1.json,%S/multi_config_2.json -instrumentor-read-config-paths-file=%S/multi_config_paths -S | FileCheck %s + +target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" + +define i32 @foo() { +; CHECK-LABEL: @foo( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = alloca i32, align 4 +; CHECK-NEXT: store i32 0, ptr [[TMP0]], align 4 +; CHECK-NEXT: call void @__c4_post_store(i32 -3) #[[ATTR0:[0-9]+]] +; CHECK-NEXT: call void @__c1_pre_load(i32 1) #[[ATTR0]] +; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +; CHECK-NEXT: call void @__c4_post_load(i32 -4) #[[ATTR0]] +; CHECK-NEXT: ret i32 [[TMP1]] +; +entry: + %0 = alloca i32, align 4 + store i32 0, ptr %0, align 4 + %2 = load i32, ptr %0, align 4 + ret i32 %2 +} + +define i32 @bar() { +; CHECK-LABEL: @bar( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = alloca i32, align 4 +; CHECK-NEXT: call void @__c2_pre_store() #[[ATTR0]] +; CHECK-NEXT: store i32 0, ptr [[TMP0]], align 4 +; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +; CHECK-NEXT: ret i32 [[TMP1]] +; +entry: + %0 = alloca i32, align 4 + store i32 0, ptr %0, align 4 + %2 = load i32, ptr %0, align 4 + ret i32 %2 +} + +define i32 @baz() { +; CHECK-LABEL: @baz( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = alloca i32, align 4 +; CHECK-NEXT: store i32 0, ptr [[TMP0]], align 4 +; CHECK-NEXT: call void @__c4_post_store(i32 -5) #[[ATTR0]] +; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +; CHECK-NEXT: call void @__c4_post_load(i32 -6) #[[ATTR0]] +; CHECK-NEXT: call void @__c3_post_load(i32 -2) #[[ATTR0]] +; CHECK-NEXT: ret i32 [[TMP1]] +; +entry: + %0 = alloca i32, align 4 + store i32 0, ptr %0, align 4 + %2 = load i32, ptr %0, align 4 + ret i32 %2 +} diff --git a/llvm/test/Instrumentation/Instrumentor/multi_config_1.json b/llvm/test/Instrumentation/Instrumentor/multi_config_1.json new file mode 100644 index 0000000000000..5452e4ea0cbd6 --- /dev/null +++ b/llvm/test/Instrumentation/Instrumentor/multi_config_1.json @@ -0,0 +1,12 @@ +{ + "configuration": { + "runtime_prefix": "__c1_", + "function_regex": "foo" + }, + "instruction_pre": { + "load": { + "enabled": true, + "id": true + } + } +} diff --git a/llvm/test/Instrumentation/Instrumentor/multi_config_2.json b/llvm/test/Instrumentation/Instrumentor/multi_config_2.json new file mode 100644 index 0000000000000..dbd1cff9540d2 --- /dev/null +++ b/llvm/test/Instrumentation/Instrumentor/multi_config_2.json @@ -0,0 +1,12 @@ +{ + "configuration": { + "runtime_prefix": "__c2_", + "function_regex": "bar" + }, + "instruction_pre": { + "store": { + "enabled": true, + "id": false + } + } +} diff --git a/llvm/test/Instrumentation/Instrumentor/multi_config_3.json b/llvm/test/Instrumentation/Instrumentor/multi_config_3.json new file mode 100644 index 0000000000000..dce4b65060b0c --- /dev/null +++ b/llvm/test/Instrumentation/Instrumentor/multi_config_3.json @@ -0,0 +1,12 @@ +{ + "configuration": { + "runtime_prefix": "__c3_", + "function_regex": "baz" + }, + "instruction_post": { + "load": { + "enabled": true, + "id": true + } + } +} diff --git a/llvm/test/Instrumentation/Instrumentor/multi_config_4.json b/llvm/test/Instrumentation/Instrumentor/multi_config_4.json new file mode 100644 index 0000000000000..0c38911f572ea --- /dev/null +++ b/llvm/test/Instrumentation/Instrumentor/multi_config_4.json @@ -0,0 +1,16 @@ +{ + "configuration": { + "runtime_prefix": "__c4_", + "function_regex": "foo|baz" + }, + "instruction_post": { + "load": { + "enabled": true, + "id": true + }, + "store": { + "enabled": true, + "id": true + } + } +} diff --git a/llvm/test/Instrumentation/Instrumentor/multi_config_paths b/llvm/test/Instrumentation/Instrumentor/multi_config_paths new file mode 100644 index 0000000000000..d32b3b97aadcd --- /dev/null +++ b/llvm/test/Instrumentation/Instrumentor/multi_config_paths @@ -0,0 +1,2 @@ +multi_config_3.json +multi_config_4.json diff --git a/llvm/test/Instrumentation/Instrumentor/read_config.ll b/llvm/test/Instrumentation/Instrumentor/read_config.ll index 519093cef72e2..a0cfb54bbf879 100644 --- a/llvm/test/Instrumentation/Instrumentor/read_config.ll +++ b/llvm/test/Instrumentation/Instrumentor/read_config.ll @@ -1,5 +1,5 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5 -; RUN: opt < %s -passes=instrumentor -instrumentor-read-config-file=%S/custom_config.json -S | FileCheck %s +; RUN: opt < %s -passes=instrumentor -instrumentor-read-config-files=%S/custom_config.json -S | FileCheck %s target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
