https://github.com/jdoerfert updated https://github.com/llvm/llvm-project/pull/196235
>From 527a1e834ba484106a4c697c34e94163b99b0a9d 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 +++++------ .../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 +- 21 files changed, 247 insertions(+), 45 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 15a2714652a3f..36f1762bcde43 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 0caf07a1e9496..a0e2ff79f95fb 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 -I%llvm_bin_dir/include/ -I%llvm_src_dir/include/ %S/UnreachableRT.cpp -o %t.UnreachableRT.o -c -// RUN: %clangxx -O0 -L%llvm_bin_dir/lib -lLLVMSupport -lLLVMDemangle -mllvm -enable-instrumentor -mllvm -instrumentor-read-config-file=%S/UnreachableRT.json %t.UnreachableRT.o -o %t %s +// RUN: %clangxx -O0 -L%llvm_bin_dir/lib -lLLVMSupport -lLLVMDemangle -mllvm -enable-instrumentor -mllvm -instrumentor-read-config-files=%S/UnreachableRT.json %t.UnreachableRT.o -o %t %s // RUN: %t 2>&1 | FileCheck %s --check-prefix=FIRST // RUN: %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 63a37931e98dc..84622a0b4d1bf 100644 --- a/llvm/include/llvm/Transforms/IPO/Instrumentor.h +++ b/llvm/include/llvm/Transforms/IPO/Instrumentor.h @@ -347,7 +347,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( @@ -370,6 +379,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 cae68f4b34f08..a709b979e64e6 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); +/// 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); + } // end namespace instrumentor } // end namespace llvm diff --git a/llvm/lib/Transforms/IPO/Instrumentor.cpp b/llvm/lib/Transforms/IPO/Instrumentor.cpp index 23fbeb9e7ec33..0465c1c03c839 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" @@ -61,17 +62,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 @@ -129,13 +138,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(); @@ -315,15 +330,39 @@ bool InstrumentorImpl::instrument() { 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)) - 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); + + 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)) + 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 a2707193da1a7..ab8015019822b 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 <string> @@ -221,5 +223,40 @@ bool readConfigFromJSON(InstrumentationConfig &IConf, StringRef InputFile, return true; } +bool readConfigPathsFile(StringRef InputFile, cl::list<std::string> &Configs, + LLVMContext &Ctx) { + if (InputFile.empty()) + return true; + + std::error_code EC; + auto BufferOrErr = MemoryBuffer::getFileOrSTDIN(InputFile); + if (std::error_code EC = BufferOrErr.getError()) { + Ctx.diagnose(DiagnosticInfoInstrumentation( + Twine("failed to open instrumentor configuration file for reading: ") + + EC.message(), + 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/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
