LLVM 23.0.0git
Instrumentor.h
Go to the documentation of this file.
1//===-- Instrumentor.h - Highly configurable instrumentation pass ---------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// The Instrumentor, a highly configurable instrumentation pass.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_TRANSFORMS_IPO_INSTRUMENTOR_H
14#define LLVM_TRANSFORMS_IPO_INSTRUMENTOR_H
15
16#include "llvm/ADT/DenseMap.h"
19#include "llvm/ADT/MapVector.h"
20#include "llvm/ADT/StringMap.h"
21#include "llvm/ADT/StringRef.h"
23#include "llvm/IR/Constants.h"
24#include "llvm/IR/DataLayout.h"
25#include "llvm/IR/IRBuilder.h"
26#include "llvm/IR/Instruction.h"
28#include "llvm/IR/LLVMContext.h"
29#include "llvm/IR/Module.h"
30#include "llvm/IR/PassManager.h"
36
37#include <cstdint>
38#include <functional>
39#include <memory>
40#include <string>
41#include <tuple>
42
43namespace llvm {
44namespace instrumentor {
45
48
49/// Callback type for getting/setting a value for a instrumented opportunity.
50///{
51using GetterCallbackTy = std::function<Value *(
53using SetterCallbackTy = std::function<Value *(
55///}
56
57/// Helper to represent an argument to an instrumentation runtime function.
58struct IRTArg {
59 /// Flags describing the possible properties of an argument.
61 NONE = 0,
62 STRING = 1 << 0,
63 REPLACABLE = 1 << 1,
68 };
69
70 /// Construct an argument.
77
78 /// Whether the argument is enabled and should be passed to the function call.
79 bool Enabled;
80
81 /// The type of the argument.
83
84 /// A string with the name of the argument.
86
87 /// A string with the description of the argument.
89
90 /// The flags that describe the properties of the argument. Multiple flags may
91 /// be specified.
92 unsigned Flags;
93
94 /// The callback for getting the value of the argument.
96
97 /// The callback for consuming the output value of the argument.
99
100 /// Whether the argument value can be cached between the PRE and POST calls.
102};
103
104/// Helper to represent an instrumentation runtime function that is related to
105/// an instrumentation opportunity.
107 /// Construct an instrumentation function description linked to the \p IO
108 /// instrumentation opportunity and \p RetTy return type.
110
111 /// Create the type of the instrumentation function.
114 const DataLayout &DL,
115 bool ForceIndirection);
116
117 /// Create a call instruction that calls to the instrumentation function and
118 /// passes the corresponding arguments.
121 InstrumentationCaches &ICaches);
122
123 /// Create a string representation of the function declaration in C. Two
124 /// strings are returned: the function definition with direct arguments and
125 /// the function with any indirect argument.
126 std::pair<std::string, std::string>
127 createCSignature(const InstrumentationConfig &IConf) const;
128
129 /// Create a string representation of the function definition in C. The
130 /// function body implements a stub and only prints the passed arguments. Two
131 /// strings are returned: the function definition with direct arguments and
132 /// the function with any indirect argument.
133 std::pair<std::string, std::string> createCBodies() const;
134
135 /// Return whether the \p IRTA argument can be replaced.
136 bool isReplacable(IRTArg &IRTA) const {
138 }
139
140 /// Return whether the function may have any indirect argument.
141 bool isPotentiallyIndirect(IRTArg &IRTA) const {
142 return ((IRTA.Flags & IRTArg::POTENTIALLY_INDIRECT) ||
144 }
145
146 /// Whether the function requires indirection in some argument.
148
149 /// Whether any argument may require indirection.
151
152 /// The number of arguments that can be replaced.
153 unsigned NumReplaceableArgs = 0;
154
155 /// The instrumentation opportunity which it is linked to.
157
158 /// The return type of the instrumentation function.
159 Type *RetTy = nullptr;
160};
161
162/// Helper to represent an instrumentation location, which is composed of an
163/// instrumentation opportunity type and a position.
165 /// The supported location kinds, which are composed of a opportunity type and
166 /// position. The PRE position indicates the instrumentation function call is
167 /// inserted before the instrumented event occurs. The POST position indicates
168 /// the instrumentation call is inserted after the event occurs. Some
169 /// opportunity types may only support one position.
183
184 /// Construct an instrumentation location that is not instrumenting an
185 /// instruction.
186 InstrumentationLocation(KindTy Kind) : Kind(Kind) {
187 assert(Kind != INSTRUCTION_PRE && Kind != INSTRUCTION_POST &&
188 "Opcode required!");
189 }
190
191 /// Construct an instrumentation location belonging to the instrumentation of
192 /// an instruction.
193 InstrumentationLocation(unsigned Opcode, bool IsPRE)
194 : Kind(IsPRE ? INSTRUCTION_PRE : INSTRUCTION_POST), Opcode(Opcode) {}
195
196 /// Return the type and position.
197 KindTy getKind() const { return Kind; }
198
199 /// Return the string representation given a location kind. This is the string
200 /// used in the configuration file.
202 switch (Kind) {
203 case MODULE_PRE:
204 return "module_pre";
205 case MODULE_POST:
206 return "module_post";
207 case GLOBAL_PRE:
208 return "global_pre";
209 case GLOBAL_POST:
210 return "global_post";
211 case FUNCTION_PRE:
212 return "function_pre";
213 case FUNCTION_POST:
214 return "function_post";
215 case BASIC_BLOCK_PRE:
216 return "basic_block_pre";
217 case BASIC_BLOCK_POST:
218 return "basic_block_post";
219 case INSTRUCTION_PRE:
220 return "instruction_pre";
221 case INSTRUCTION_POST:
222 return "instruction_post";
223 }
224 llvm_unreachable("Invalid kind!");
225 }
226
227 /// Return the location kind described by a string.
229 return StringSwitch<KindTy>(S)
230 .Case("module_pre", MODULE_PRE)
231 .Case("module_post", MODULE_POST)
232 .Case("global_pre", GLOBAL_PRE)
233 .Case("global_post", GLOBAL_POST)
234 .Case("function_pre", FUNCTION_PRE)
235 .Case("function_post", FUNCTION_POST)
236 .Case("basic_block_pre", BASIC_BLOCK_PRE)
237 .Case("basic_block_post", BASIC_BLOCK_POST)
238 .Case("instruction_pre", INSTRUCTION_PRE)
239 .Case("instruction_post", INSTRUCTION_POST)
240 .Default(Last);
241 }
242
243 /// Return whether a location kind is positioned before the event occurs.
244 static bool isPRE(KindTy Kind) {
245 switch (Kind) {
246 case MODULE_PRE:
247 case GLOBAL_PRE:
248 case FUNCTION_PRE:
249 case BASIC_BLOCK_PRE:
250 case INSTRUCTION_PRE:
251 return true;
252 case MODULE_POST:
253 case GLOBAL_POST:
254 case FUNCTION_POST:
255 case BASIC_BLOCK_POST:
256 case INSTRUCTION_POST:
257 return false;
258 }
259 llvm_unreachable("Invalid kind!");
260 }
261
262 /// Return whether the instrumentation location is before the event occurs.
263 bool isPRE() const { return isPRE(Kind); }
264
265 /// Get the opcode of the instruction instrumentation location. This function
266 /// may not be called by a non-instruction instrumentation location.
267 unsigned getOpcode() const {
268 assert((Kind == INSTRUCTION_PRE || Kind == INSTRUCTION_POST) &&
269 "Expected instruction!");
270 return Opcode;
271 }
272
273private:
274 /// The kind (type and position) of the instrumentation location.
275 const KindTy Kind;
276
277 /// The opcode for instruction instrumentation locations.
278 const unsigned Opcode = -1;
279};
280
281/// An option for the base configuration.
283 /// The possible types of options.
288
289 /// Create a boolean option with \p Name name, \p Description description and
290 /// \p DefaultValue as boolean default value.
291 static std::unique_ptr<BaseConfigurationOption>
293 StringRef Description, bool DefaultValue);
294
295 /// Create a string option with \p Name name, \p Description description and
296 /// \p DefaultValue as string default value.
297 static std::unique_ptr<BaseConfigurationOption>
299 StringRef Description, StringRef DefaultValue);
300
301 /// Helper union that holds any possible option type.
302 union ValueTy {
303 bool Bool;
305 };
306
307 /// Set and get of the boolean value. Only valid if it is a boolean option.
308 ///{
309 void setBool(bool B) {
310 assert(Kind == BOOLEAN && "Not a boolean!");
311 Value.Bool = B;
312 }
313 bool getBool() const {
314 assert(Kind == BOOLEAN && "Not a boolean!");
315 return Value.Bool;
316 }
317 ///}
318
319 /// Set and get the string value. Only valid if it is a boolean option.
320 ///{
322 assert(Kind == STRING && "Not a string!");
323 Value.String = S;
324 }
326 assert(Kind == STRING && "Not a string!");
327 return Value.String;
328 }
329 ///}
330
331 /// The information of the option.
332 ///{
337 ///}
338
339 /// Construct a base configuration option.
342};
343
344/// The class that contains the configuration for the instrumentor. It holds the
345/// information for each instrumented opportunity, including the base
346/// configuration options. Another class may inherit from this one to modify the
347/// default behavior.
350
351 /// Construct an instrumentation configuration with the base options.
353
354 /// Initialize the config to a clean base state without loosing cached values
355 /// that can be reused across configurations.
357 // Clear previous configurations but not the caches.
359 for (auto &Map : IChoices)
360 Map.clear();
361
363 *this, "runtime_prefix", "The runtime API prefix.", "__instrumentor_");
365 *this, "runtime_stubs_file",
366 "The file into which runtime stubs should be written.", "");
368 *this, "target_regex",
369 "Regular expression to be matched against the module target. "
370 "Only targets that match this regex will be instrumented.",
371 "");
373 *this, "function_regex",
374 "Regular expression to be matched against a function name. "
375 "Only functions that match this regex will be instrumented.",
376 "");
378 *this, "demangle_function_names",
379 "Demangle functions names passed to the runtime.", true);
381 *this, "host_enabled", "Instrument non-GPU targets", true);
383 *this, "gpu_enabled", "Instrument GPU targets", true);
384 populate(IIRB);
385 }
386
387 /// Populate the instrumentation opportunities.
388 virtual void populate(InstrumentorIRBuilderTy &IIRB);
389
390 /// Get the runtime prefix for the instrumentation runtime functions.
391 StringRef getRTName() const { return RuntimePrefix->getString(); }
392
393 /// Get the instrumentation function name.
394 std::string getRTName(StringRef Prefix, StringRef Name,
395 StringRef Suffix1 = "", StringRef Suffix2 = "") const {
396 return (getRTName() + Prefix + Name + Suffix1 + Suffix2).str();
397 }
398
399 /// Add the base configuration option \p BCO into the list of base options.
401 BaseConfigurationOptions.push_back(BCO);
402 }
403
404 /// Register instrumentation opportunity \p IO.
406
407 /// Allocate an object of type \p Ty using a bump allocator and construct it
408 /// with the \p Args arguments. The object may not be freed manually.
409 template <typename Ty, typename... ArgsTy>
410 static Ty *allocate(ArgsTy &&...Args) {
412 Ty *Obj = Allocator.Allocate();
413 new (Obj) Ty(std::forward<ArgsTy>(Args)...);
414 return Obj;
415 }
416
417 /// Mapping to remember global strings passed to the runtime.
419
420 /// Mapping from constants to globals with the constant as initializer.
422
424 Constant *&V = GlobalStringsMap[SS.save(S)];
425 if (!V) {
426 auto &M = *IIRB.IRB.GetInsertBlock()->getModule();
427 V = IIRB.IRB.CreateGlobalString(
428 S, getRTName() + ".str",
429 M.getDataLayout().getDefaultGlobalsAddressSpace(), &M);
430 if (V->getType() != IIRB.IRB.getPtrTy())
431 V = ConstantExpr::getAddrSpaceCast(V, IIRB.IRB.getPtrTy());
432 }
433 return V;
434 }
435 /// The list of enabled base configuration options.
437
438 /// The base configuration options.
439 std::unique_ptr<BaseConfigurationOption> RuntimePrefix;
440 std::unique_ptr<BaseConfigurationOption> RuntimeStubsFile;
441 std::unique_ptr<BaseConfigurationOption> DemangleFunctionNames;
442 std::unique_ptr<BaseConfigurationOption> TargetRegex;
443 std::unique_ptr<BaseConfigurationOption> FunctionRegex;
444 std::unique_ptr<BaseConfigurationOption> HostEnabled;
445 std::unique_ptr<BaseConfigurationOption> GPUEnabled;
446
447 /// The map registered instrumentation opportunities. The map is indexed by
448 /// the instrumentation location kind and then by the opportunity name. Notice
449 /// that an instrumentation location may have more than one instrumentation
450 /// opportunity registered.
454
455 /// Utilities for allocating and building strings.
456 ///{
459 ///}
460};
461
462/// Base class for instrumentation opportunities. All opportunities should
463/// inherit from this class and implement the virtual class members.
466
467 /// Construct an opportunity with location \p IP.
469
470 /// The instrumentation location of the opportunity.
472
473 /// The list of possible arguments for the instrumentation runtime function.
474 /// The order within the array determines the order of arguments. Arguments
475 /// may be disabled and will not be passed to the function call.
477
478 /// Whether the opportunity is enabled.
479 bool Enabled = true;
480
481 /// A filter expression to be matched against runtime property values. If the
482 /// filter is non-empty, only instrumentations matching the filter will be
483 /// executed. The filter syntax supports:
484 /// - Integer comparisons: ==, !=, <, >, <=, >=
485 /// - String comparisons: ==, != (with quoted strings)
486 /// - String prefix check: startswith("prefix")
487 /// - Logical operators: &&, ||
488 /// Examples:
489 /// "sync_scope_id==3 && atomicity_ordering>0"
490 /// "name==\"foo\" || name.startswith(\"test_\")"
491 /// If a property value is dynamic (not a constant), the filter is assumed to
492 /// pass (true).
494
495 /// Helpers to cast values, pass them to the runtime, and replace them. To be
496 /// used as part of the getter/setter of a InstrumentationOpportunity.
497 ///{
498 static Value *forceCast(Value &V, Type &Ty, InstrumentorIRBuilderTy &IIRB);
501 return forceCast(V, Ty, IIRB);
502 }
503 static Value *replaceValue(Value &V, Value &NewV,
506 ///}
507
508 /// Instrument the value \p V using the configuration \p IConf, and
509 /// potentially, the caches \p ICaches.
510 virtual Value *instrument(Value *&V, bool &Changed,
513 InstrumentationCaches &ICaches) {
514 if (CB && !CB(*V))
515 return nullptr;
516
517 // Check if the filter matches before instrumenting
518 if (!evaluateFilter(*V, Changed, *this, IConf, IIRB))
519 return nullptr;
520
521 Changed = true;
522 const DataLayout &DL = IIRB.IRB.GetInsertBlock()->getDataLayout();
523 IRTCallDescription IRTCallDesc(*this, getRetTy(V->getContext()));
524 auto *CI = IRTCallDesc.createLLVMCall(V, IConf, IIRB, DL, ICaches);
525 return CI;
526 }
527
528 /// Get the return type for the instrumentation runtime function.
529 virtual Type *getRetTy(LLVMContext &Ctx) const { return nullptr; }
530
531 /// Get the name of the instrumentation opportunity.
532 virtual StringRef getName() const = 0;
533
534 /// Get the opcode of the instruction instrumentation opportunity. Only valid
535 /// if it is instruction instrumentation.
536 unsigned getOpcode() const { return IP.getOpcode(); }
537
538 /// Get the location kind of the instrumentation opportunity.
540 return IP.getKind();
541 }
542
543 /// An optional callback that takes the value that is about to be
544 /// instrumented and can return false if it should be skipped.
545 ///{
546 using CallbackTy = std::function<bool(Value &)>;
547 CallbackTy CB = nullptr;
548 ///}
549
550 /// Add arguments available in all instrumentation opportunities.
552 bool PassId) {
553 const auto CB = IP.isPRE() ? getIdPre : getIdPost;
554 if (PassId) {
555 IRTArgs.push_back(
557 "A unique ID associated with the given instrumentor call",
558 IRTArg::NONE, CB, nullptr, true, true));
559 }
560 }
561
562 /// Get the opportunity identifier for the pre and post positions.
563 ///{
564 static Value *getIdPre(Value &V, Type &Ty, InstrumentationConfig &IConf,
566 static Value *getIdPost(Value &V, Type &Ty, InstrumentationConfig &IConf,
568 ///}
569
570 /// Compute the opportunity identifier for the current instrumentation epoch
571 /// \p CurrentEpoch. The identifiers are assigned consecutively as the epoch
572 /// advances. Epochs may have no identifier assigned (e.g., because no id was
573 /// requested). This function always returns the same identifier when called
574 /// multiple times with the same epoch.
575 static int32_t getIdFromEpoch(uint32_t CurrentEpoch) {
576 static DenseMap<uint32_t, int32_t> EpochIdMap;
577 static int32_t GlobalId = 0;
578 int32_t &EpochId = EpochIdMap[CurrentEpoch];
579 if (EpochId == 0)
580 EpochId = ++GlobalId;
581 return EpochId;
582 }
583};
584
585/// The base instrumentation opportunity class for instruction opportunities.
586/// Each instruction opportunity should inherit from this class and implement
587/// the virtual class members.
588template <unsigned Opcode>
590 virtual ~InstructionIO() {}
591
592 /// Construct an instruction opportunity.
595
596 /// Get the name of the instruction.
597 StringRef getName() const override {
598 return Instruction::getOpcodeName(Opcode);
599 }
600};
601
602/// The instrumentation opportunity for functions.
609
620
621 struct ConfigTy final : public BaseConfigTy<ConfigKind> {
622 std::function<bool(Argument &)> ArgFilter;
623
626
627 StringRef getName() const override { return "function"; }
628
630 ConfigTy *UserConfig = nullptr);
631
632 static Value *getFunctionAddress(Value &V, Type &Ty,
635 static Value *getFunctionName(Value &V, Type &Ty,
644 static Value *isMainFunction(Value &V, Type &Ty, InstrumentationConfig &IConf,
646
647 static void populate(InstrumentationConfig &IConf,
649 auto *PreIO = IConf.allocate<FunctionIO>(true);
650 PreIO->init(IConf, IIRB);
651 auto *PostIO = IConf.allocate<FunctionIO>(false);
652 PostIO->init(IConf, IIRB);
653 }
654};
655
656/// The instrumentation opportunity for alloca instructions.
657struct AllocaIO final : public InstructionIO<Instruction::Alloca> {
658 AllocaIO(bool IsPRE) : InstructionIO(IsPRE) {}
659
669
672
674 ConfigTy *UserConfig = nullptr);
675
676 static Value *getSize(Value &V, Type &Ty, InstrumentationConfig &IConf,
678 static Value *setSize(Value &V, Value &NewV, InstrumentationConfig &IConf,
680 static Value *getAlignment(Value &V, Type &Ty, InstrumentationConfig &IConf,
682
683 static void populate(InstrumentationConfig &IConf,
685 auto *PreIO = IConf.allocate<AllocaIO>(true);
686 PreIO->init(IConf, IIRB);
687 auto *PostIO = IConf.allocate<AllocaIO>(false);
688 PostIO->init(IConf, IIRB);
689 }
690};
691
692struct UnreachableIO final : public InstructionIO<Instruction::Unreachable> {
693 UnreachableIO() : InstructionIO<Instruction::Unreachable>(/*IsPRE=*/true) {}
694
699
702
704 ConfigTy *UserConfig = nullptr);
705
706 static void populate(InstrumentationConfig &IConf,
708 auto *PreIO = IConf.allocate<UnreachableIO>();
709 PreIO->init(IConf, IIRB);
710 }
711};
712
713// Module instrumentation opportunity.
715 ModuleIO(bool IsPRE)
717 IsPRE ? InstrumentationLocation::MODULE_PRE
718 : InstrumentationLocation::MODULE_POST)) {}
719
726
729
730 StringRef getName() const override { return "module"; }
731
733 ConfigTy *UserConfig = nullptr);
734
735 static Value *getModuleName(Value &V, Type &Ty, InstrumentationConfig &IConf,
737 static Value *getTargetTriple(Value &V, Type &Ty,
740
741 static void populate(InstrumentationConfig &IConf,
743 auto *PreIO = IConf.allocate<ModuleIO>(true);
744 PreIO->init(IConf, IIRB);
745 auto *PostIO = IConf.allocate<ModuleIO>(false);
746 PostIO->init(IConf, IIRB);
747 }
748};
749
750// Global variable instrumentation opportunity.
756
770
773
774 StringRef getName() const override { return "global"; }
775
777 ConfigTy *UserConfig = nullptr);
778
779 static Value *getAddress(Value &V, Type &Ty, InstrumentationConfig &IConf,
781 static Value *setAddress(Value &V, Value &NewV, InstrumentationConfig &IConf,
783 static Value *getAS(Value &V, Type &Ty, InstrumentationConfig &IConf,
785 static Value *getDeclaredSize(Value &V, Type &Ty,
788 static Value *getAlignment(Value &V, Type &Ty, InstrumentationConfig &IConf,
790 static Value *getSymbolName(Value &V, Type &Ty, InstrumentationConfig &IConf,
792 static Value *getInitialValue(Value &V, Type &Ty,
795 static Value *isConstant(Value &V, Type &Ty, InstrumentationConfig &IConf,
797 static Value *isDefinition(Value &V, Type &Ty, InstrumentationConfig &IConf,
799
800 static void populate(InstrumentationConfig &IConf,
802 auto *PreIO = IConf.allocate<GlobalVarIO>(true);
803 PreIO->init(IConf, IIRB);
804 auto *PostIO = IConf.allocate<GlobalVarIO>(false);
805 PostIO->init(IConf, IIRB);
806 }
807};
808
809/// The instrumentation opportunity for store instructions.
810struct StoreIO : public InstructionIO<Instruction::Store> {
811 virtual ~StoreIO() {};
812
813 /// Construct a store instruction opportunity.
814 StoreIO(bool IsPRE) : InstructionIO(IsPRE) {}
815
816 /// The selector of arguments for store opportunities.
817 ///{
832
835 ///}
836
837 /// Get the type of the stored value.
839 return IIRB.Int64Ty;
840 }
841
842 /// Initialize the store opportunity using the instrumentation config \p IConf
843 /// and the user config \p UserConfig.
845 ConfigTy *UserConfig = nullptr);
846
847 /// Getters and setters for the arguments of the instrumentation function for
848 /// the store opportunity.
849 ///{
850 static Value *getPointer(Value &V, Type &Ty, InstrumentationConfig &IConf,
852 static Value *setPointer(Value &V, Value &NewV, InstrumentationConfig &IConf,
854 static Value *getPointerAS(Value &V, Type &Ty, InstrumentationConfig &IConf,
856 static Value *getValue(Value &V, Type &Ty, InstrumentationConfig &IConf,
858 static Value *getValueSize(Value &V, Type &Ty, InstrumentationConfig &IConf,
860 static Value *getAlignment(Value &V, Type &Ty, InstrumentationConfig &IConf,
862 static Value *getValueTypeId(Value &V, Type &Ty, InstrumentationConfig &IConf,
864 static Value *getAtomicityOrdering(Value &V, Type &Ty,
867 static Value *getSyncScopeId(Value &V, Type &Ty, InstrumentationConfig &IConf,
869 static Value *isVolatile(Value &V, Type &Ty, InstrumentationConfig &IConf,
871 ///}
872
873 /// Create the store opportunities for pre and post positions. The
874 /// opportunities are also initialized with the arguments for their
875 /// instrumentation calls.
876 static void populate(InstrumentationConfig &IConf,
878 auto *PreIO = IConf.allocate<StoreIO>(true);
879 PreIO->init(IConf, IIRB);
880 auto *PostIO = IConf.allocate<StoreIO>(false);
881 PostIO->init(IConf, IIRB);
882 }
883};
884
885/// The instrumentation opportunity for load instructions.
886struct LoadIO : public InstructionIO<Instruction::Load> {
887 virtual ~LoadIO() {};
888
889 /// Construct a load opportunity.
890 LoadIO(bool IsPRE) : InstructionIO(IsPRE) {}
891
892 /// The selector of arguments for load opportunities.
893 ///{
909
912 ///}
913
914 /// Get the type of the loaded value.
916 return IIRB.Int64Ty;
917 }
918
919 /// Initialize the load opportunity using the instrumentation config \p IConf
920 /// and the user config \p UserConfig.
922 ConfigTy *UserConfig = nullptr);
923
924 /// Getters and setters for the arguments of the instrumentation function for
925 /// the load opportunity.
926 ///{
927 static Value *getPointer(Value &V, Type &Ty, InstrumentationConfig &IConf,
929 static Value *setPointer(Value &V, Value &NewV, InstrumentationConfig &IConf,
931 static Value *getPointerAS(Value &V, Type &Ty, InstrumentationConfig &IConf,
933 static Value *getValue(Value &V, Type &Ty, InstrumentationConfig &IConf,
935 static Value *getValueSize(Value &V, Type &Ty, InstrumentationConfig &IConf,
937 static Value *getAlignment(Value &V, Type &Ty, InstrumentationConfig &IConf,
939 static Value *getValueTypeId(Value &V, Type &Ty, InstrumentationConfig &IConf,
941 static Value *getAtomicityOrdering(Value &V, Type &Ty,
944 static Value *getSyncScopeId(Value &V, Type &Ty, InstrumentationConfig &IConf,
946 static Value *isVolatile(Value &V, Type &Ty, InstrumentationConfig &IConf,
948 ///}
949
950 /// Create the store opportunities for PRE and POST positions.
951 static void populate(InstrumentationConfig &IConf,
953 auto *PreIO = IConf.allocate<LoadIO>(true);
954 PreIO->init(IConf, IIRB);
955 auto *PostIO = IConf.allocate<LoadIO>(false);
956 PostIO->init(IConf, IIRB);
957 }
958};
959
960} // namespace instrumentor
961
962/// The Instrumentor pass.
963class InstrumentorPass : public RequiredPassInfoMixin<InstrumentorPass> {
964 using InstrumentationConfig = instrumentor::InstrumentationConfig;
965 using InstrumentorIRBuilderTy = instrumentor::InstrumentorIRBuilderTy;
966
967 /// File system to be used for read operations.
969
970 /// The configuration and IR builder provided by the user.
971 InstrumentationConfig *UserIConf;
972 InstrumentorIRBuilderTy *UserIIRB;
973
974 PreservedAnalyses run(Module &M, InstrumentationConfig &IConf,
975 InstrumentorIRBuilderTy &IIRB, bool ReadConfig);
976
977public:
978 /// Construct an instrumentor pass that will use the instrumentation
979 /// configuration \p IC and the IR builder \p IIRB. If an IR builder is not
980 /// provided, a default builder is used. When the configuration is not
981 /// provided, it is read from the config file if available and otherwise a
982 /// default configuration is used.
984 InstrumentationConfig *IC = nullptr,
985 InstrumentorIRBuilderTy *IIRB = nullptr);
986
988};
989
990} // end namespace llvm
991
992#endif // LLVM_TRANSFORMS_IPO_INSTRUMENTOR_H
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file defines the StringMap class.
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
This file defines the BumpPtrAllocator interface.
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
This file defines the DenseMap class.
This file defines an array type that can be indexed using scoped enum values.
Module.h This file contains the declarations for the Module class.
This header defines various interfaces for pass management in LLVM.
This file defines the RefCountedBase, ThreadSafeRefCountedBase, and IntrusiveRefCntPtr classes.
This file implements a map that provides insertion order iteration.
ModuleAnalysisManager MAM
Basic Register Allocator
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
This class represents an incoming formal argument to a Function.
Definition Argument.h:32
This class represents a function call, abstracting a target machine's calling convention.
static LLVM_ABI Constant * getAddrSpaceCast(Constant *C, Type *Ty, bool OnlyIfReduced=false)
This is an important base class in LLVM.
Definition Constant.h:43
A parsed version of the target data layout string in and methods for querying it.
Definition DataLayout.h:64
Class to represent function types.
const char * getOpcodeName() const
InstrumentorPass(IntrusiveRefCntPtr< vfs::FileSystem > FS=nullptr, InstrumentationConfig *IC=nullptr, InstrumentorIRBuilderTy *IIRB=nullptr)
Construct an instrumentor pass that will use the instrumentation configuration IC and the IR builder ...
A smart pointer to a reference-counted object that inherits from RefCountedBase or ThreadSafeRefCount...
This is an important class for using LLVM in a threaded context.
Definition LLVMContext.h:68
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:67
A set of analyses that are preserved following a run of a transformation pass.
Definition Analysis.h:112
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
A BumpPtrAllocator that allows only elements of a specific type to be allocated.
Definition Allocator.h:390
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
Saves strings in the provided stable storage and returns a StringRef with a stable character pointer.
Definition StringSaver.h:22
A switch()-like statement whose cases are string literals.
StringSwitch & Case(StringLiteral S, T Value)
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
Definition Type.cpp:313
LLVM Value Representation.
Definition Value.h:75
Changed
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
std::function< Value *( Value &, Value &, InstrumentationConfig &, InstrumentorIRBuilderTy &)> SetterCallbackTy
LLVM_ABI bool evaluateFilter(Value &V, bool &Changed, InstrumentationOpportunity &IO, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
Evaluate the filter expression against the current instrumentation opportunity.
std::function< Value *( Value &, Type &, InstrumentationConfig &, InstrumentorIRBuilderTy &)> GetterCallbackTy
Callback type for getting/setting a value for a instrumented opportunity.
This is an optimization pass for GlobalISel generic memory operations.
Op::Description Desc
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1916
BumpPtrAllocatorImpl<> BumpPtrAllocator
The standard BumpPtrAllocator which just uses the default template parameters.
Definition Allocator.h:383
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.
Definition MIRParser.h:39
@ Enable
Enable colors.
Definition WithColor.h:47
Implement std::hash so that hash_code can be used in STL containers.
Definition BitVector.h:874
A CRTP mix-in for passes that should not be skipped.
static void populate(InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
void init(InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB, ConfigTy *UserConfig=nullptr)
}
BaseConfigTy< ConfigKind > ConfigTy
static Value * getSize(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static Value * setSize(Value &V, Value &NewV, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static Value * getAlignment(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
Boolean option bitset with a compile-time number of bits to store as many options as the enumeration ...
An option for the base configuration.
void setBool(bool B)
Set and get of the boolean value.
static std::unique_ptr< BaseConfigurationOption > createStringOption(InstrumentationConfig &IC, StringRef Name, StringRef Description, StringRef DefaultValue)
Create a string option with Name name, Description description and DefaultValue as string default val...
BaseConfigurationOption(StringRef Name, StringRef Desc, KindTy Kind)
}
KindTy
The possible types of options.
static std::unique_ptr< BaseConfigurationOption > createBoolOption(InstrumentationConfig &IC, StringRef Name, StringRef Description, bool DefaultValue)
Create a boolean option with Name name, Description description and DefaultValue as boolean default v...
std::function< bool(Argument &)> ArgFilter
llvm::instrumentor::FunctionIO::ConfigTy Config
static void populate(InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
StringRef getName() const override
Get the name of the instrumentation opportunity.
Value * setArguments(Value &V, Value &NewV, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static Value * getFunctionAddress(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static Value * isMainFunction(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
Value * getArguments(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
Value * getNumArguments(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static Value * getFunctionName(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
void init(InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB, ConfigTy *UserConfig=nullptr)
FunctionIO {.
static Value * setAddress(Value &V, Value &NewV, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
void init(InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB, ConfigTy *UserConfig=nullptr)
static Value * getAS(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static Value * getAlignment(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static Value * getInitialValue(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static Value * isDefinition(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static Value * getDeclaredSize(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
StringRef getName() const override
Get the name of the instrumentation opportunity.
static Value * getSymbolName(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static void populate(InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static Value * getAddress(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
BaseConfigTy< ConfigKind > ConfigTy
static Value * isConstant(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
GetterCallbackTy GetterCB
The callback for getting the value of the argument.
StringRef Description
A string with the description of the argument.
unsigned Flags
The flags that describe the properties of the argument.
Type * Ty
The type of the argument.
IRTArg(Type *Ty, StringRef Name, StringRef Description, unsigned Flags, GetterCallbackTy GetterCB, SetterCallbackTy SetterCB=nullptr, bool Enabled=true, bool NoCache=false)
Construct an argument.
bool Enabled
Whether the argument is enabled and should be passed to the function call.
SetterCallbackTy SetterCB
The callback for consuming the output value of the argument.
StringRef Name
A string with the name of the argument.
bool NoCache
Whether the argument value can be cached between the PRE and POST calls.
IRArgFlagTy
Flags describing the possible properties of an argument.
Helper to represent an instrumentation runtime function that is related to an instrumentation opportu...
bool isReplacable(IRTArg &IRTA) const
Return whether the IRTA argument can be replaced.
IRTCallDescription(InstrumentationOpportunity &IO, Type *RetTy=nullptr)
Construct an instrumentation function description linked to the IO instrumentation opportunity and Re...
bool MightRequireIndirection
Whether any argument may require indirection.
std::pair< std::string, std::string > createCBodies() const
Create a string representation of the function definition in C.
CallInst * createLLVMCall(Value *&V, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB, const DataLayout &DL, InstrumentationCaches &ICaches)
Create a call instruction that calls to the instrumentation function and passes the corresponding arg...
Type * RetTy
The return type of the instrumentation function.
InstrumentationOpportunity & IO
The instrumentation opportunity which it is linked to.
FunctionType * createLLVMSignature(InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB, const DataLayout &DL, bool ForceIndirection)
Create the type of the instrumentation function.
std::pair< std::string, std::string > createCSignature(const InstrumentationConfig &IConf) const
Create a string representation of the function declaration in C.
unsigned NumReplaceableArgs
The number of arguments that can be replaced.
bool RequiresIndirection
Whether the function requires indirection in some argument.
bool isPotentiallyIndirect(IRTArg &IRTA) const
Return whether the function may have any indirect argument.
InstructionIO(bool IsPRE)
Construct an instruction opportunity.
StringRef getName() const override
Get the name of the instruction.
Helper that represent the caches for instrumentation call arguments.
The class that contains the configuration for the instrumentor.
virtual void populate(InstrumentorIRBuilderTy &IIRB)
Populate the instrumentation opportunities.
void addChoice(InstrumentationOpportunity &IO, LLVMContext &Ctx)
Register instrumentation opportunity IO.
Constant * getGlobalString(StringRef S, InstrumentorIRBuilderTy &IIRB)
std::unique_ptr< BaseConfigurationOption > HostEnabled
std::unique_ptr< BaseConfigurationOption > DemangleFunctionNames
void init(InstrumentorIRBuilderTy &IIRB)
Initialize the config to a clean base state without loosing cached values that can be reused across c...
EnumeratedArray< MapVector< StringRef, InstrumentationOpportunity * >, InstrumentationLocation::KindTy > IChoices
The map registered instrumentation opportunities.
std::unique_ptr< BaseConfigurationOption > GPUEnabled
DenseMap< Constant *, GlobalVariable * > ConstantGlobalsCache
Mapping from constants to globals with the constant as initializer.
BumpPtrAllocator StringAllocator
Utilities for allocating and building strings.
std::string getRTName(StringRef Prefix, StringRef Name, StringRef Suffix1="", StringRef Suffix2="") const
Get the instrumentation function name.
std::unique_ptr< BaseConfigurationOption > RuntimeStubsFile
StringRef getRTName() const
Get the runtime prefix for the instrumentation runtime functions.
void addBaseChoice(BaseConfigurationOption *BCO)
Add the base configuration option BCO into the list of base options.
static Ty * allocate(ArgsTy &&...Args)
Allocate an object of type Ty using a bump allocator and construct it with the Args arguments.
SmallVector< BaseConfigurationOption * > BaseConfigurationOptions
The list of enabled base configuration options.
InstrumentationConfig()
Construct an instrumentation configuration with the base options.
std::unique_ptr< BaseConfigurationOption > FunctionRegex
std::unique_ptr< BaseConfigurationOption > TargetRegex
std::unique_ptr< BaseConfigurationOption > RuntimePrefix
The base configuration options.
DenseMap< StringRef, Constant * > GlobalStringsMap
Mapping to remember global strings passed to the runtime.
Helper to represent an instrumentation location, which is composed of an instrumentation opportunity ...
unsigned getOpcode() const
Get the opcode of the instruction instrumentation location.
KindTy getKind() const
Return the type and position.
InstrumentationLocation(KindTy Kind)
Construct an instrumentation location that is not instrumenting an instruction.
static KindTy getKindFromStr(StringRef S)
Return the location kind described by a string.
static StringRef getKindStr(KindTy Kind)
Return the string representation given a location kind.
KindTy
The supported location kinds, which are composed of a opportunity type and position.
static bool isPRE(KindTy Kind)
Return whether a location kind is positioned before the event occurs.
bool isPRE() const
Return whether the instrumentation location is before the event occurs.
InstrumentationLocation(unsigned Opcode, bool IsPRE)
Construct an instrumentation location belonging to the instrumentation of an instruction.
Base class for instrumentation opportunities.
InstrumentationLocation::KindTy getLocationKind() const
Get the location kind of the instrumentation opportunity.
bool Enabled
Whether the opportunity is enabled.
static Value * getIdPre(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
Get the opportunity identifier for the pre and post positions.
virtual Value * instrument(Value *&V, bool &Changed, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB, InstrumentationCaches &ICaches)
}
static Value * forceCast(Value &V, Type &Ty, InstrumentorIRBuilderTy &IIRB)
Helpers to cast values, pass them to the runtime, and replace them.
static int32_t getIdFromEpoch(uint32_t CurrentEpoch)
}
std::function< bool(Value &)> CallbackTy
An optional callback that takes the value that is about to be instrumented and can return false if it...
static Value * getIdPost(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static Value * getValue(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static Value * replaceValue(Value &V, Value &NewV, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
unsigned getOpcode() const
Get the opcode of the instruction instrumentation opportunity.
virtual StringRef getName() const =0
Get the name of the instrumentation opportunity.
InstrumentationLocation IP
The instrumentation location of the opportunity.
InstrumentationOpportunity(const InstrumentationLocation IP)
Construct an opportunity with location IP.
SmallVector< IRTArg > IRTArgs
The list of possible arguments for the instrumentation runtime function.
void addCommonArgs(InstrumentationConfig &IConf, LLVMContext &Ctx, bool PassId)
}
virtual Type * getRetTy(LLVMContext &Ctx) const
Get the return type for the instrumentation runtime function.
StringRef Filter
A filter expression to be matched against runtime property values.
An IR builder augmented with extra information for the instrumentor pass.
IRBuilder< ConstantFolder, IRBuilderCallbackInserter > IRB
The underlying IR builder with insertion callback.
LoadIO(bool IsPRE)
Construct a load opportunity.
static Value * getValueSize(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static Value * getSyncScopeId(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static Value * getAtomicityOrdering(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
virtual Type * getValueType(InstrumentorIRBuilderTy &IIRB) const
}
static Value * getValue(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
ConfigKind
The selector of arguments for load opportunities.
static Value * getAlignment(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static Value * getPointer(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
Getters and setters for the arguments of the instrumentation function for the load opportunity.
static Value * isVolatile(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static Value * setPointer(Value &V, Value &NewV, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
BaseConfigTy< ConfigKind > ConfigTy
static Value * getPointerAS(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static void populate(InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
}
static Value * getValueTypeId(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
void init(InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB, ConfigTy *UserConfig=nullptr)
Initialize the load opportunity using the instrumentation config IConf and the user config UserConfig...
static Value * getModuleName(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static void populate(InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static Value * getTargetTriple(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
void init(InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB, ConfigTy *UserConfig=nullptr)
BaseConfigTy< ConfigKind > ConfigTy
StringRef getName() const override
Get the name of the instrumentation opportunity.
static Value * getPointer(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
Getters and setters for the arguments of the instrumentation function for the store opportunity.
static void populate(InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
}
static Value * getValueTypeId(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
virtual Type * getValueType(InstrumentorIRBuilderTy &IIRB) const
}
static Value * getSyncScopeId(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static Value * getPointerAS(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
ConfigKind
The selector of arguments for store opportunities.
static Value * getAlignment(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static Value * getValue(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static Value * setPointer(Value &V, Value &NewV, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static Value * isVolatile(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static Value * getValueSize(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
BaseConfigTy< ConfigKind > ConfigTy
void init(InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB, ConfigTy *UserConfig=nullptr)
Initialize the store opportunity using the instrumentation config IConf and the user config UserConfi...
static Value * getAtomicityOrdering(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
StoreIO(bool IsPRE)
Construct a store instruction opportunity.
static void populate(InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
void init(InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB, ConfigTy *UserConfig=nullptr)
}
BaseConfigTy< ConfigKind > ConfigTy
Helper union that holds any possible option type.