LLVM 24.0.0git
Instrumentor.cpp
Go to the documentation of this file.
1//===-- Instrumentor.cpp - 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 implementation of the Instrumentor, a highly configurable instrumentation
10// pass.
11//
12//===----------------------------------------------------------------------===//
13
15#include "IPOOptions.h"
19
21#include "llvm/ADT/STLExtras.h"
25#include "llvm/ADT/StringMap.h"
26#include "llvm/ADT/iterator.h"
29#include "llvm/IR/Constant.h"
30#include "llvm/IR/Constants.h"
31#include "llvm/IR/DataLayout.h"
34#include "llvm/IR/Dominators.h"
35#include "llvm/IR/Function.h"
36#include "llvm/IR/IRBuilder.h"
37#include "llvm/IR/InstrTypes.h"
38#include "llvm/IR/Instruction.h"
41#include "llvm/IR/Intrinsics.h"
42#include "llvm/IR/LLVMContext.h"
43#include "llvm/IR/Metadata.h"
44#include "llvm/IR/Module.h"
45#include "llvm/IR/PassManager.h"
46#include "llvm/IR/Verifier.h"
48#include "llvm/Linker/Linker.h"
51#include "llvm/Support/Regex.h"
57
58#include <cassert>
59#include <cstdint>
60#include <functional>
61#include <iterator>
62#include <memory>
63#include <string>
64#include <type_traits>
65
66using namespace llvm;
67using namespace llvm::instrumentor;
68
69#define DEBUG_TYPE "instrumentor"
70
71namespace {
72
73/// The user option to specify input JSON files to read the configuration from.
75 ConfigFiles("instrumentor-read-config-files",
76 cl::desc("Read the instrumentor configuration from the "
77 "specified JSON files (comma separated)"),
79
80/// Set the debug location, if not set, after changing the insertion point of
81/// the IR builder \p IRB.
82template <typename IRBuilderTy> void ensureDbgLoc(IRBuilderTy &IRB) {
83 if (IRB.getCurrentDebugLocation())
84 return;
85 auto *BB = IRB.GetInsertBlock();
86 if (auto *SP = BB->getParent()->getSubprogram())
87 IRB.SetCurrentDebugLocation(DILocation::get(BB->getContext(), 0, 0, SP));
88}
89
90/// Attempt to cast \p V to type \p Ty using only bit-preserving casts.
91/// This ensures that floating-point values are converted via bitcast (not
92/// fptosi/fptoui) to preserve their exact bit representation.
93template <typename IRBTy>
94Value *tryToCast(IRBTy &IRB, Value *V, Type *Ty, const DataLayout &DL,
95 bool AllowTruncate = false) {
96 if (!V)
98 Type *VTy = V->getType();
99 if (VTy == Ty)
100 return V;
101 if (VTy->isAggregateType() || VTy->isVectorTy())
102 return V;
103 if (VTy->isPointerTy() && Ty->isPointerTy())
104 return IRB.CreatePointerBitCastOrAddrSpaceCast(V, Ty);
105 TypeSize RequestedSize = DL.getTypeSizeInBits(Ty);
106 TypeSize ValueSize = DL.getTypeSizeInBits(VTy);
107 bool ShouldTruncate = RequestedSize < ValueSize;
108 if (ShouldTruncate && !AllowTruncate)
109 return V;
110 if (ShouldTruncate && AllowTruncate) {
111 // First convert to integer of the same size if needed.
112 Value *IntV = V;
113 if (VTy->isFloatingPointTy())
114 IntV = IRB.CreateBitCast(V, IRB.getIntNTy(ValueSize));
115 return tryToCast(IRB,
116 IRB.CreateIntCast(IntV, IRB.getIntNTy(RequestedSize),
117 /*IsSigned=*/false),
118 Ty, DL, AllowTruncate);
119 }
120 if (VTy->isIntegerTy() && Ty->isIntegerTy())
121 return IRB.CreateIntCast(V, Ty, /*IsSigned=*/false);
122 // Use bit-preserving casts for floating-point values: convert float to int
123 // of the same size via bitcast, then extend/truncate the integer if needed.
124 if (VTy->isFloatingPointTy() && Ty->isIntOrPtrTy()) {
125 return tryToCast(IRB, IRB.CreateBitCast(V, IRB.getIntNTy(ValueSize)), Ty,
126 DL, AllowTruncate);
127 }
128 // When converting int to float, never use sitofp/uitofp as they perform value
129 // conversion, not bit-preserving cast.
130 if (VTy->isIntegerTy() && Ty->isFloatingPointTy()) {
131 if (ValueSize == RequestedSize)
132 return IRB.CreateBitCast(V, Ty);
133 return tryToCast(
134 IRB,
135 IRB.CreateIntCast(V, IRB.getIntNTy(RequestedSize), /*IsSigned=*/false),
136 Ty, DL, AllowTruncate);
137 }
138 return IRB.CreateBitOrPointerCast(V, Ty);
139}
140
141/// Get a constant integer/boolean of type \p IT and value \p Val.
142template <typename Ty>
143Constant *getCI(Type *IT, Ty Val, bool IsSigned = false) {
144 return ConstantInt::get(IT, Val, IsSigned);
145}
146
147Constant *getSubTypeID(Type &OpTy, Type &ReqTy) {
148 switch (OpTy.getTypeID()) {
149 case Type::TypeID::ArrayTyID:
150 case Type::TypeID::FixedVectorTyID:
151 case Type::TypeID::ScalableVectorTyID:
152 return getCI(&ReqTy, OpTy.getContainedType(0)->getTypeID());
153 default:
154 break;
155 }
156
157 return getCI(&ReqTy, -1, /*IsSigned=*/true);
158}
159
160/// The core of the instrumentor pass, which instruments the module as the
161/// instrumentation configuration mandates.
162class InstrumentorImpl final {
163public:
164 /// Construct an instrumentor implementation using the configuration \p IConf.
165 InstrumentorImpl(InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB,
166 Module &M)
167 : IConf(IConf), M(M), IIRB(IIRB) {}
168
169 /// Instrument the module, public entry point.
170 bool instrument();
171
172 // Reset the state to allow reuse of the instrumentor with a different
173 // configuration.
174 void clear() {
175 InstChoicesPRE.clear();
176 InstChoicesPOST.clear();
177 ParsedFunctionRegex = Regex();
178 }
179
180private:
181 /// Link the runtime bitcodes into the module. Returns true if the module
182 /// was changed.
183 bool linkRuntime();
184
185 /// Indicate if the module should be instrumented based on the target.
186 bool shouldInstrumentTarget();
187
188 /// Indicate if the function \p Fn should be instrumented.
189 bool shouldInstrumentFunction(Function &Fn);
190 bool shouldInstrumentGlobalVariable(GlobalVariable &GV);
191
192 /// Instrument instruction \p I if needed, and use the argument caches in \p
193 /// ICaches.
194 bool instrumentInstruction(Instruction &I, InstrumentationCaches &ICaches);
195
196 /// Instrument function \p Fn.
197 bool instrumentFunction(Function &Fn);
198 bool instrumentModule();
199
200 /// The instrumentation opportunities for instructions indexed by
201 /// their opcode.
203 InstChoicesPOST;
204
205 /// The instrumentor configuration.
207
208 /// The function regex filter, if any.
209 Regex ParsedFunctionRegex;
210
211 /// The underlying module.
212 Module &M;
213
214protected:
215 /// A special IR builder that keeps track of the inserted instructions.
217};
218
219} // end anonymous namespace
220
222 if (!Str.empty()) {
223 Regex RX(Str);
224 std::string ErrMsg;
225 if (!RX.isValid(ErrMsg)) {
227 Twine("failed to parse ") + Name + " regex: " + ErrMsg, DS_Error));
228 return Regex();
229 }
230 return RX;
231 }
232 return Regex();
233}
234
235bool InstrumentorImpl::linkRuntime() {
236 ArrayRef<StringRef> RuntimeBitcodes = IConf.RuntimeBitcodes->getStringList();
237 if (RuntimeBitcodes.empty())
238 return false;
239
240 bool Changed = false;
241
242 for (StringRef RuntimeBitcode : RuntimeBitcodes) {
243 if (RuntimeBitcode.empty())
244 continue;
245
246 SMDiagnostic Err;
247 auto RTM = parseIRFile(RuntimeBitcode, Err, M.getContext());
248 if (!RTM) {
249 IIRB.Ctx.diagnose(DiagnosticInfoInstrumentation(
250 Twine("Failed to parse runtime bitcode file '") + RuntimeBitcode +
251 Twine("': ") + Err.getMessage(),
252 DS_Error));
253 return Changed;
254 }
255
256 if (Linker::linkModules(M, std::move(RTM))) {
257 IIRB.Ctx.diagnose(DiagnosticInfoInstrumentation(
258 Twine("Failed to link in runtime bitcode file '") + RuntimeBitcode +
259 "'",
260 DS_Error));
261 return Changed;
262 }
263 Changed = true;
264 }
265
266 if (!IConf.InlineRuntimeEagerly->getBool())
267 return Changed;
268
269 for (auto [I, _] : IIRB.NewInsts) {
270 auto *CI = dyn_cast<CallInst>(I);
271 if (!CI || isa<IntrinsicInst>(CI))
272 continue;
273
274 InlineFunctionInfo IFI;
275 auto InlineResult = InlineFunction(*CI, IFI);
276 if (!InlineResult.isSuccess()) {
277 std::string WarnMsg;
278 raw_string_ostream SS(WarnMsg);
279 SS << "Inlining of runtime call failed: "
280 << CI->getCalledFunction()->getName() << "\n";
281 SS << "Reason: " << InlineResult.getFailureReason() << "\n";
282 SS << "Signatures: " << *CI->getFunctionType() << " vs "
283 << *CI->getCalledFunction()->getFunctionType() << "\n";
284 IIRB.Ctx.diagnose(DiagnosticInfoInstrumentation(WarnMsg, DS_Warning));
285 }
286 }
287
288 // Promote any eligible instrumentor-associated allocas to registers.
289 for (auto It : IIRB.AllocaMap) {
290 auto *Fn = It.first.first;
291 DominatorTree DT(*Fn);
292 auto &Allocas = *It.second;
293 erase_if(Allocas,
294 [](const AllocaInst *AI) { return !isAllocaPromotable(AI); });
295 PromoteMemToReg(Allocas, DT);
296 delete It.second;
297 }
298 IIRB.AllocaMap.clear();
299 return Changed;
300}
301
302bool InstrumentorImpl::shouldInstrumentTarget() {
303 const Triple &T = M.getTargetTriple();
304 const bool IsGPU = T.isAMDGPU() || T.isNVPTX();
305
306 bool RegexMatches = true;
307 Regex RX = createRegex(IConf.TargetRegex->getString(), "target", IIRB.Ctx);
308 if (RX.isValid())
309 RegexMatches = RX.match(T.str());
310
311 // Only instrument the module if the target has to be instrumented.
312 return ((IsGPU && IConf.GPUEnabled->getBool()) ||
313 (!IsGPU && IConf.HostEnabled->getBool())) &&
314 RegexMatches;
315}
316
317bool InstrumentorImpl::shouldInstrumentFunction(Function &Fn) {
318 if (Fn.isDeclaration())
319 return false;
320 if (Fn.hasFnAttribute(Attribute::DisableSanitizerInstrumentation))
321 return false;
322 bool RegexMatches = true;
323 if (ParsedFunctionRegex.isValid())
324 RegexMatches = ParsedFunctionRegex.match(Fn.getName());
325 return (RegexMatches && !Fn.getName().starts_with(IConf.getRTName())) ||
326 Fn.hasFnAttribute("instrument");
327}
328
329bool InstrumentorImpl::shouldInstrumentGlobalVariable(GlobalVariable &GV) {
330 return !GV.getName().starts_with("llvm.") &&
331 !GV.getName().starts_with(IConf.getRTName());
332}
333
334bool InstrumentorImpl::instrumentInstruction(Instruction &I,
335 InstrumentationCaches &ICaches) {
336 bool Changed = false;
337
338 // Skip instrumentation instructions.
339 if (IIRB.NewInsts.contains(&I))
340 return Changed;
341
342 // Count epochs eagerly.
343 ++IIRB.Epoch;
344
345 Value *IPtr = &I;
346 if (auto *IO = InstChoicesPRE.lookup(I.getOpcode())) {
347 IIRB.IRB.SetInsertPoint(&I);
348 ensureDbgLoc(IIRB.IRB);
349 IO->instrument(IPtr, Changed, IConf, IIRB, ICaches);
350 }
351
352 if (auto *IO = InstChoicesPOST.lookup(I.getOpcode())) {
353 IIRB.IRB.SetInsertPoint(I.getNextNode());
354 ensureDbgLoc(IIRB.IRB);
355 IO->instrument(IPtr, Changed, IConf, IIRB, ICaches);
356 }
357 IIRB.returnAllocas();
358
359 return Changed;
360}
361
362bool InstrumentorImpl::instrumentFunction(Function &Fn) {
363 bool Changed = false;
364 if (!shouldInstrumentFunction(Fn))
365 return Changed;
366
367 InstrumentationCaches ICaches;
368 SmallVector<Instruction *> FinalTIs;
369 ReversePostOrderTraversal<Function *> RPOT(&Fn);
370 for (auto &It : RPOT) {
371 for (auto &I : *It)
372 Changed |= instrumentInstruction(I, ICaches);
373
374 auto *TI = It->getTerminator();
375 if (!TI->getNumSuccessors())
376 FinalTIs.push_back(TI);
377 }
378
379 Value *FPtr = &Fn;
380 for (auto &[Name, IO] :
382 if (!IO->Enabled)
383 continue;
384 // Count epochs eagerly.
385 ++IIRB.Epoch;
386
387 IIRB.IRB.SetInsertPoint(
388 cast<Function>(FPtr)->getEntryBlock().getFirstNonPHIOrAlloca());
389 ensureDbgLoc(IIRB.IRB);
390 IO->instrument(FPtr, Changed, IConf, IIRB, ICaches);
391 IIRB.returnAllocas();
392 }
393
394 for (auto &[Name, IO] :
396 if (!IO->Enabled)
397 continue;
398 // Count epochs eagerly.
399 ++IIRB.Epoch;
400
401 for (Instruction *FinalTI : FinalTIs) {
402 IIRB.IRB.SetInsertPoint(FinalTI);
403 ensureDbgLoc(IIRB.IRB);
404 IO->instrument(FPtr, Changed, IConf, IIRB, ICaches);
405 IIRB.returnAllocas();
406 }
407 }
408 return Changed;
409}
410
411bool InstrumentorImpl::instrumentModule() {
413 Globals.reserve(M.global_size());
414 for (GlobalVariable &GV : M.globals()) {
415 // llvm.metadata contains globals such as llvm.used.
416 if (GV.getSection() == "llvm.metadata" ||
417 GV.getName() == "llvm.global_dtors" ||
418 GV.getName() == "llvm.global_ctors")
419 continue;
420 Globals.push_back(&GV);
421 }
422
423 auto CreateYtor = [&](bool Ctor) {
424 Function *YtorFn = Function::Create(
425 FunctionType::get(IIRB.VoidTy, false), GlobalValue::PrivateLinkage,
426 IConf.getRTName(Ctor ? "ctor" : "dtor", ""), M);
427
428 auto *EntryBB = BasicBlock::Create(IIRB.Ctx, "entry", YtorFn);
429 IIRB.IRB.SetInsertPoint(EntryBB->begin());
430 ensureDbgLoc(IIRB.IRB);
431 IIRB.IRB.CreateRetVoid();
432
433 if (Ctor)
434 appendToGlobalCtors(M, YtorFn, 1000);
435 else
436 appendToGlobalDtors(M, YtorFn, 1000);
437 return YtorFn;
438 };
439
440 InstrumentationCaches ICaches;
441
442 Function *CtorFn = nullptr, *DtorFn = nullptr;
443 bool Changed = false;
446 bool IsPRE = InstrumentationLocation::isPRE(Loc);
447 Function *&YtorFn = IsPRE ? CtorFn : DtorFn;
448 for (auto &ChoiceIt : IConf.IChoices[Loc]) {
449 auto *IO = ChoiceIt.second;
450 if (!IO->Enabled)
451 continue;
452 if (!YtorFn) {
453 YtorFn = CreateYtor(IsPRE);
454 Changed = true;
455 }
456 IIRB.IRB.SetInsertPointPastAllocas(YtorFn);
457 ensureDbgLoc(IIRB.IRB);
458 Value *YtorPtr = YtorFn;
459
460 // Count epochs eagerly.
461 ++IIRB.Epoch;
462
463 IO->instrument(YtorPtr, Changed, IConf, IIRB, ICaches);
464 IIRB.returnAllocas();
465 }
466 }
467
470 bool IsPRE = InstrumentationLocation::isPRE(Loc);
471 Function *&YtorFn = IsPRE ? CtorFn : DtorFn;
472 for (auto &ChoiceIt : IConf.IChoices[Loc]) {
473 auto *IO = ChoiceIt.second;
474 if (!IO->Enabled)
475 continue;
476 if (!YtorFn) {
477 YtorFn = CreateYtor(IsPRE);
478 Changed = true;
479 }
480 for (GlobalVariable *GV : Globals) {
481 if (!shouldInstrumentGlobalVariable(*GV))
482 continue;
483 if (IsPRE)
484 IIRB.IRB.SetInsertPoint(YtorFn->getEntryBlock().getTerminator());
485 else
486 IIRB.IRB.SetInsertPointPastAllocas(YtorFn);
487 ensureDbgLoc(IIRB.IRB);
488 Value *GVPtr = GV;
489
490 // Count epochs eagerly.
491 ++IIRB.Epoch;
492
493 IO->instrument(GVPtr, Changed, IConf, IIRB, ICaches);
494 IIRB.returnAllocas();
495 }
496 }
497 }
498
499 return Changed;
500}
501
502bool InstrumentorImpl::instrument() {
503 bool Changed = false;
504 if (!shouldInstrumentTarget())
505 return Changed;
506
507 StringRef FunctionRegexStr = IConf.FunctionRegex->getString();
508 ParsedFunctionRegex = createRegex(FunctionRegexStr, "function", IIRB.Ctx);
509
510 // Helper to register an IO for all its opcodes.
511 auto RegisterForAllOpcodes = [](auto &InstChoices,
512 InstrumentationOpportunity *IO) {
513 ArrayRef<unsigned> Opcodes = IO->getAllOpcodes();
514 // Register for all opcodes.
515 for (unsigned Opcode : Opcodes)
516 InstChoices[Opcode] = IO;
517 };
518
519 for (auto &[Name, IO] :
521 if (IO->Enabled)
522 RegisterForAllOpcodes(InstChoicesPRE, IO);
523 for (auto &[Name, IO] :
525 if (IO->Enabled)
526 RegisterForAllOpcodes(InstChoicesPOST, IO);
527 Changed |= instrumentModule();
528
529 for (Function &Fn : M)
530 Changed |= instrumentFunction(Fn);
531
532 Changed |= linkRuntime();
533
534 return Changed;
535}
536
538 InstrumentationConfig *IC,
539 InstrumentorIRBuilderTy *IIRB)
540 : FS(FS), UserIConf(IC), UserIIRB(IIRB) {
541 if (!FS)
542 this->FS = vfs::getRealFileSystem();
543}
544
545PreservedAnalyses InstrumentorPass::run(Module &M, InstrumentationConfig &IConf,
547 bool ReadConfig) {
548 const IPOOptions &Opts = getIPOOptions(M);
549 bool Changed = false;
550 InstrumentorImpl Impl(IConf, IIRB, M);
551
552 // If this is a configuration driven run, iterate over all configurations
553 // provided by the user, if not, use the config as is and run the instrumentor
554 // once.
555 if (ReadConfig)
556 readConfigPathsFile(Opts.instrumentor_read_config_paths_file, ConfigFiles,
557 IIRB.Ctx, *FS);
558
559 bool MultipleConfigs = ConfigFiles.size() > 1;
560 unsigned Idx = 0;
561 do {
562 std::string ConfigFile =
563 ReadConfig && !ConfigFiles.empty() ? ConfigFiles[Idx] : "";
564
565 // Initialize the config to the base state but keep the caches around.
566 Impl.clear();
567 IConf.init(IIRB);
568
569 if (!readConfigFromJSON(IConf, ConfigFile, IIRB.Ctx, *FS))
570 continue;
571
573 IConf,
574 MultipleConfigs
575 ? (Opts.instrumentor_write_config_file + "." + std::to_string(Idx))
576 .str()
577 : Opts.instrumentor_write_config_file.str(),
578 IIRB.Ctx);
579
580 printRuntimeStub(IConf, IConf.RuntimeStubsFile->getString(), IIRB.Ctx);
581
582 Changed |= Impl.instrument();
583 } while (++Idx < ConfigFiles.size());
584
585 if (!Changed)
586 return PreservedAnalyses::all();
588}
589
591 // Only create them if the user did not provide them.
592 std::unique_ptr<InstrumentationConfig> IConfInt(
593 !UserIConf ? new InstrumentationConfig() : nullptr);
594 std::unique_ptr<InstrumentorIRBuilderTy> IIRBInt(
595 !UserIIRB ? new InstrumentorIRBuilderTy(M) : nullptr);
596
597 auto *IConf = IConfInt ? IConfInt.get() : UserIConf;
598 auto *IIRB = IIRBInt ? IIRBInt.get() : UserIIRB;
599
600 auto PA = run(M, *IConf, *IIRB, !UserIConf);
601
602 assert(!verifyModule(M, &errs()));
603 return PA;
604}
605
606std::unique_ptr<BaseConfigurationOption>
609 bool DefaultValue) {
610 auto BCO =
611 std::make_unique<BaseConfigurationOption>(Name, Description, BOOLEAN);
612 BCO->setBool(DefaultValue);
613 IConf.addBaseChoice(BCO.get());
614 return BCO;
615}
616
617std::unique_ptr<BaseConfigurationOption>
621 StringRef DefaultValue) {
622 auto BCO =
623 std::make_unique<BaseConfigurationOption>(Name, Description, STRING);
624 BCO->setString(DefaultValue);
625 IConf.addBaseChoice(BCO.get());
626 return BCO;
627}
628
629std::unique_ptr<BaseConfigurationOption>
632 ArrayRef<StringRef> DefaultValue) {
633 auto BCO =
634 std::make_unique<BaseConfigurationOption>(Name, Description, STRING_LIST);
635 BCO->setStringList(DefaultValue);
636 IConf.addBaseChoice(BCO.get());
637 return BCO;
638}
639
641 /// List of all instrumentation opportunities.
642 BasePointerIO::populate(*this, IIRB);
643 ModuleIO::populate(*this, IIRB);
644 GlobalVarIO::populate(*this, IIRB);
645 FunctionIO::populate(*this, IIRB);
646 AllocaIO::populate(*this, IIRB);
647 UnreachableIO::populate(*this, IIRB);
648 LoadIO::populate(*this, IIRB);
649 StoreIO::populate(*this, IIRB);
650 CastIO::populate(*this, IIRB);
651 NumericIO::populate(*this, IIRB);
652 CompareIO::populate(*this, IIRB);
653}
654
656 LLVMContext &Ctx) {
657 auto *&ICPtr = IChoices[IO.getLocationKind()][IO.getName()];
658 if (ICPtr) {
660 Twine("registered two instrumentation opportunities for the same "
661 "location (") +
662 ICPtr->getName() + Twine(" vs ") + IO.getName() + Twine(")"),
663 DS_Warning));
664 }
665 ICPtr = &IO;
666}
667
668Value *
671 Function *Fn = IIRB.IRB.GetInsertBlock()->getParent();
672
673 Value *Obj;
674 {
675 Value *&UnderlyingObj = UnderlyingObjsMap[&V];
676 if (!UnderlyingObj)
677 UnderlyingObj = const_cast<Value *>(getUnderlyingObjectAggressive(&V));
678 Obj = UnderlyingObj;
679 }
680
681 Value *&BPI = BasePointerInfoMap[{Obj, Fn}];
682 if (BPI)
683 return BPI;
684
685 auto *BPIO =
687 if (!BPIO || !BPIO->Enabled) {
689 "Base pointer info disabled but required, passing nullptr.",
690 DS_Warning));
691 return BPI = Constant::getNullValue(BPIO->getRetTy(IIRB.Ctx));
692 }
693
695 if (auto *BasePtrI = dyn_cast<Instruction>(Obj)) {
696 std::optional<BasicBlock::iterator> IP =
697 BasePtrI->getInsertionPointAfterDef();
698 if (IP) {
699 IIRB.IRB.SetInsertPoint(*IP);
700 } else {
702 "Base pointer info could not be placed, passing nullptr.",
703 DS_Warning));
704 return BPI = Constant::getNullValue(BPIO->getRetTy(IIRB.Ctx));
705 }
706 } else if (isa<Constant>(Obj) || isa<Argument>(Obj)) {
707 IIRB.IRB.SetInsertPointPastAllocas(IIRB.IRB.GetInsertBlock()->getParent());
708 } else {
709 LLVM_DEBUG(Obj->dump());
710 llvm_unreachable("Unexpected base pointer!");
711 }
712 ensureDbgLoc(IIRB.IRB);
713
714 // Use fresh caches for safety, as this function may be called from
715 // another instrumentation opportunity.
716 bool Changed;
717 InstrumentationCaches ICaches;
718 BPI = BPIO->instrument(Obj, Changed, *this, IIRB, ICaches);
719 IIRB.returnAllocas();
720 if (!BPI)
721 BPI = Constant::getNullValue(BPIO->getRetTy(IIRB.Ctx));
722 return BPI;
723}
724
728 return getCI(&Ty, getIdFromEpoch(IIRB.Epoch));
729}
730
734 return getCI(&Ty, -getIdFromEpoch(IIRB.Epoch), /*IsSigned=*/true);
735}
736
739 if (V.getType()->isVoidTy())
740 return Ty.isVoidTy() ? &V : Constant::getNullValue(&Ty);
741 return tryToCast(IIRB.IRB, &V, &Ty, IIRB.IRB.getDataLayout());
742}
743
747 if (V.getType()->isVoidTy())
748 return &V;
749
750 auto *NewVCasted = &NewV;
751 if (auto *I = dyn_cast<Instruction>(&NewV)) {
753 IIRB.IRB.SetInsertPoint(I->getNextNode());
754 ensureDbgLoc(IIRB.IRB);
755 NewVCasted = tryToCast(IIRB.IRB, &NewV, V.getType(), IIRB.DL,
756 /*AllowTruncate=*/true);
757 }
758 V.replaceUsesWithIf(NewVCasted, [&](Use &U) {
759 if (IIRB.NewInsts.lookup(cast<Instruction>(U.getUser())) == IIRB.Epoch)
760 return false;
761 return !isa<LifetimeIntrinsic>(U.getUser()) && !U.getUser()->isDroppable();
762 });
763
764 return &V;
765}
766
768 Type *RetTy)
769 : IO(IO), RetTy(RetTy) {
770 for (auto &It : IO.IRTArgs) {
771 if (!It.Enabled)
772 continue;
773 NumReplaceableArgs += bool(It.Flags & IRTArg::REPLACABLE);
774 MightRequireIndirection |= It.Flags & IRTArg::POTENTIALLY_INDIRECT;
775 }
778}
779
782 const DataLayout &DL, bool ForceIndirection) {
783 assert(((ForceIndirection && MightRequireIndirection) ||
784 (!ForceIndirection && !RequiresIndirection)) &&
785 "Wrong indirection setting!");
786
787 SmallVector<Type *> ParamTypes;
788 for (auto &It : IO.IRTArgs) {
789 if (!It.Enabled)
790 continue;
791 if (!ForceIndirection || !isPotentiallyIndirect(It)) {
792 ParamTypes.push_back(It.Ty);
793 if (!RetTy && NumReplaceableArgs == 1 && (It.Flags & IRTArg::REPLACABLE))
794 RetTy = It.Ty;
795 continue;
796 }
797
798 // The indirection pointer and the size of the value.
799 ParamTypes.push_back(IIRB.PtrTy);
800 if (!(It.Flags & IRTArg::INDIRECT_HAS_SIZE))
801 ParamTypes.push_back(IIRB.Int32Ty);
802 }
803 if (!RetTy)
804 RetTy = IIRB.VoidTy;
805
806 return FunctionType::get(RetTy, ParamTypes, /*isVarArg=*/false);
807}
808
812 const DataLayout &DL,
813 InstrumentationCaches &ICaches) {
814 SmallVector<Value *> CallParams;
815
817 auto IP = IIRB.IRB.GetInsertPoint();
818
819 bool ForceIndirection = RequiresIndirection;
820 for (auto &It : IO.IRTArgs) {
821 if (!It.Enabled)
822 continue;
823 auto *&Param = ICaches.DirectArgCache[{IIRB.Epoch, IO.getName(), It.Name}];
824 if (!Param || It.NoCache)
825 // Avoid passing the caches to the getter.
826 Param = It.GetterCB(*V, *It.Ty, IConf, IIRB);
827 assert(Param);
828
829 if (Param->getType()->isVoidTy()) {
830 Param = Constant::getNullValue(It.Ty);
831 } else if (Param->getType()->isAggregateType() ||
832 Param->getType()->isVectorTy() ||
833 DL.getTypeSizeInBits(Param->getType()) >
834 DL.getTypeSizeInBits(It.Ty)) {
835 if (!isPotentiallyIndirect(It)) {
837 Twine("indirection needed for ") + It.Name + Twine(" in ") +
838 IO.getName() +
839 Twine(", but not indicated. Instrumentation is skipped"),
840 DS_Warning));
841 return nullptr;
842 }
843 ForceIndirection = true;
844 } else {
845 Param = tryToCast(IIRB.IRB, Param, It.Ty, DL);
846 }
847 CallParams.push_back(Param);
848 }
849
850 if (ForceIndirection) {
851 Function *Fn = IIRB.IRB.GetInsertBlock()->getParent();
852
853 unsigned Offset = 0;
854 for (auto &It : IO.IRTArgs) {
855 if (!It.Enabled)
856 continue;
857
858 if (!isPotentiallyIndirect(It)) {
859 ++Offset;
860 continue;
861 }
862 auto *&CallParam = CallParams[Offset++];
863 if (!(It.Flags & IRTArg::INDIRECT_HAS_SIZE)) {
864 CallParams.insert(&CallParam + 1, IIRB.IRB.getInt32(DL.getTypeStoreSize(
865 CallParam->getType())));
866 Offset += 1;
867 }
868
869 auto *&CachedParam =
870 ICaches.IndirectArgCache[{IIRB.Epoch, IO.getName(), It.Name}];
871 if (CachedParam) {
872 CallParam = CachedParam;
873 continue;
874 }
875
876 auto *AI = IIRB.getAlloca(Fn, CallParam->getType());
877 IIRB.IRB.CreateStore(CallParam, AI);
878 CallParam = CachedParam = tryToCast(IIRB.IRB, AI, IIRB.PtrTy, DL);
879 }
880 }
881
882 if (!ForceIndirection)
883 IIRB.IRB.SetInsertPoint(IP);
884 ensureDbgLoc(IIRB.IRB);
885
886 auto *FnTy = createLLVMSignature(IConf, IIRB, DL, ForceIndirection);
887 auto CompleteName =
888 IConf.getRTName(IO.IP.isPRE() ? "pre_" : "post_", IO.getName(),
889 ForceIndirection ? "_ind" : "");
890 auto FC = IIRB.IRB.getModule()->getOrInsertFunction(CompleteName, FnTy);
891 auto *CI = IIRB.IRB.CreateCall(FC, CallParams);
892 CI->addFnAttr(Attribute::get(IIRB.Ctx, Attribute::WillReturn));
893
894 for (unsigned I = 0, E = IO.IRTArgs.size(); I < E; ++I) {
895 if (!IO.IRTArgs[I].Enabled)
896 continue;
897 if (!isReplacable(IO.IRTArgs[I]))
898 continue;
899 bool IsCustomReplaceable = IO.IRTArgs[I].Flags & IRTArg::REPLACABLE_CUSTOM;
900 Value *NewValue = FnTy->isVoidTy() || IsCustomReplaceable
901 ? ICaches.DirectArgCache[{IIRB.Epoch, IO.getName(),
902 IO.IRTArgs[I].Name}]
903 : CI;
904 assert(NewValue);
905 if (ForceIndirection && !IsCustomReplaceable &&
906 isPotentiallyIndirect(IO.IRTArgs[I])) {
907 auto *Q =
908 ICaches
909 .IndirectArgCache[{IIRB.Epoch, IO.getName(), IO.IRTArgs[I].Name}];
910 NewValue = IIRB.IRB.CreateLoad(V->getType(), Q);
911 }
912 V = IO.IRTArgs[I].SetterCB(*V, *NewValue, IConf, IIRB);
913 }
914 return CI;
915}
916
917template <typename Ty> constexpr static Value *getValue(Ty &ValueOrUse) {
918 if constexpr (std::is_same<Ty, Use>::value)
919 return ValueOrUse.get();
920 else
921 return static_cast<Value *>(&ValueOrUse);
922}
923
924template <typename Range>
927 auto *Fn = IIRB.IRB.GetInsertBlock()->getParent();
928 auto *I32Ty = IIRB.IRB.getInt32Ty();
929 SmallVector<Constant *> ConstantValues;
932 for (auto &RE : R) {
933 Value *V = getValue(RE);
934 if (!V->getType()->isSized())
935 continue;
936 auto VSize = IIRB.DL.getTypeAllocSize(V->getType());
937 ConstantValues.push_back(getCI(I32Ty, VSize));
938 Types.push_back(I32Ty);
939 ConstantValues.push_back(getCI(I32Ty, V->getType()->getTypeID()));
940 Types.push_back(I32Ty);
941 if (uint32_t MisAlign = VSize % 8) {
942 Types.push_back(ArrayType::get(IIRB.Int8Ty, 8 - MisAlign));
943 ConstantValues.push_back(ConstantArray::getNullValue(Types.back()));
944 }
945 Types.push_back(V->getType());
946 if (auto *C = dyn_cast<Constant>(V)) {
947 ConstantValues.push_back(C);
948 continue;
949 }
950 Values.push_back({V, ConstantValues.size()});
951 ConstantValues.push_back(Constant::getNullValue(V->getType()));
952 }
953 if (Types.empty())
954 return ConstantPointerNull::get(IIRB.PtrTy);
955
956 StructType *STy = StructType::get(Fn->getContext(), Types, /*isPacked=*/true);
957 Constant *Initializer = ConstantStruct::get(STy, ConstantValues);
958
959 GlobalVariable *&GV = IConf.ConstantGlobalsCache[Initializer];
960 if (!GV)
961 GV = new GlobalVariable(*Fn->getParent(), STy, false,
962 GlobalValue::InternalLinkage, Initializer,
963 IConf.getRTName("", "value_pack"));
964
965 auto *AI = IIRB.getAlloca(Fn, STy);
966 IIRB.IRB.CreateMemCpy(AI, AI->getAlign(), GV, GV->getAlign(),
967 IIRB.DL.getTypeAllocSize(STy));
968 for (auto [Param, Idx] : Values) {
969 auto *Ptr = IIRB.IRB.CreateStructGEP(STy, AI, Idx);
970 IIRB.IRB.CreateStore(Param, Ptr);
971 }
972 return AI;
973}
974
975template <typename Range>
976static void readValuePack(const Range &R, Value &Pack,
978 function_ref<void(int, Value *)> SetterCB) {
979 auto *Fn = IIRB.IRB.GetInsertBlock()->getParent();
980 auto &DL = Fn->getDataLayout();
981 unsigned Offset = 0;
982 for (const auto &[Idx, RE] : enumerate(R)) {
983 Value *V = getValue(RE);
984 if (!V->getType()->isSized())
985 continue;
986 Offset += 8;
987 auto VSize = DL.getTypeAllocSize(V->getType());
988 auto Padding = alignTo(VSize, 8) - VSize;
989 Offset += Padding;
990 auto *Ptr = IIRB.IRB.CreateConstInBoundsGEP1_32(IIRB.Int8Ty, &Pack, Offset);
991 auto *NewV = IIRB.IRB.CreateLoad(V->getType(), Ptr);
992 SetterCB(Idx, NewV);
993 Offset += VSize;
994 }
995}
996
1000 auto &I = cast<Instruction>(V);
1001 return getCI(&Ty, I.getOpcode());
1002}
1003
1005 InstrumentationConfig &IConf,
1007 auto &I = cast<Instruction>(V);
1008 auto &DL = I.getDataLayout();
1009 return getCI(&Ty, DL.getTypeStoreSize(V.getType()));
1010}
1011
1013 InstrumentationConfig &IConf,
1015 auto &I = cast<Instruction>(V);
1016 return I.getOperand(0);
1017}
1018
1020 InstrumentationConfig &IConf,
1022 auto &I = cast<Instruction>(V);
1023 if (I.getNumOperands() > 1)
1024 return I.getOperand(1);
1025 return PoisonValue::get(&Ty);
1026}
1027
1029 InstrumentationConfig &IConf,
1031 return getCI(&Ty, V.getType()->getTypeID());
1032}
1033
1035 InstrumentationConfig &IConf,
1037 return getSubTypeID(*V.getType(), Ty);
1038}
1039
1040/// FunctionIO
1041/// {
1043 InstrumentorIRBuilderTy &IIRB, ConfigTy *UserConfig) {
1044 using namespace std::placeholders;
1045 if (UserConfig)
1046 Config = *UserConfig;
1047
1049 if (Config.has(PassAddress))
1050 IRTArgs.push_back(IRTArg(IIRB.PtrTy, "address", "The function address.",
1052 if (Config.has(PassName))
1053 IRTArgs.push_back(IRTArg(IIRB.PtrTy, "name", "The function name.",
1055 if (Config.has(PassNumArguments))
1056 IRTArgs.push_back(
1057 IRTArg(IIRB.Int32Ty, "num_arguments",
1058 "Number of function arguments (without varargs).", IRTArg::NONE,
1059 std::bind(&FunctionIO::getNumArguments, this, _1, _2, _3, _4)));
1060 if (Config.has(PassArguments))
1061 IRTArgs.push_back(IRTArg(
1062 IIRB.PtrTy, "arguments", "Description of the arguments.",
1064 : IRTArg::NONE) |
1066 std::bind(&FunctionIO::getArguments, this, _1, _2, _3, _4),
1067 std::bind(&FunctionIO::setArguments, this, _1, _2, _3, _4)));
1068 if (Config.has(PassIsMain))
1069 IRTArgs.push_back(IRTArg(IIRB.Int8Ty, "is_main",
1070 "Flag to indicate it is the main function.",
1072 addCommonArgs(IConf, IIRB.Ctx, Config.has(PassId));
1073 IConf.addChoice(*this, IIRB.Ctx);
1074}
1075
1077 InstrumentationConfig &IConf,
1079 auto &Fn = cast<Function>(V);
1080 if (Fn.isIntrinsic())
1081 return Constant::getNullValue(&Ty);
1082 return &V;
1083}
1085 InstrumentationConfig &IConf,
1087 auto &Fn = cast<Function>(V);
1088 return IConf.getGlobalString(IConf.DemangleFunctionNames->getBool()
1089 ? demangle(Fn.getName())
1090 : Fn.getName(),
1091 IIRB);
1092}
1094 InstrumentationConfig &IConf,
1096 auto &Fn = cast<Function>(V);
1097 if (!Config.ArgFilter)
1098 return getCI(&Ty, Fn.arg_size());
1099 auto FRange = make_filter_range(Fn.args(), Config.ArgFilter);
1100 return getCI(&Ty, std::distance(FRange.begin(), FRange.end()));
1101}
1103 InstrumentationConfig &IConf,
1105 auto &Fn = cast<Function>(V);
1106 if (!Config.ArgFilter)
1107 return createValuePack(Fn.args(), IConf, IIRB);
1108 return createValuePack(make_filter_range(Fn.args(), Config.ArgFilter), IConf,
1109 IIRB);
1110}
1112 InstrumentationConfig &IConf,
1114 auto &Fn = cast<Function>(V);
1115 auto *AIt = Fn.arg_begin();
1116 auto CB = [&](int Idx, Value *ReplV) {
1117 while (Config.ArgFilter && !Config.ArgFilter(*AIt))
1118 ++AIt;
1119 Fn.getArg(Idx)->replaceUsesWithIf(ReplV, [&](Use &U) {
1120 return IIRB.NewInsts.lookup(cast<Instruction>(U.getUser())) != IIRB.Epoch;
1121 });
1122 ++AIt;
1123 };
1124 if (!Config.ArgFilter)
1125 readValuePack(Fn.args(), NewV, IIRB, CB);
1126 else
1127 readValuePack(make_filter_range(Fn.args(), Config.ArgFilter), NewV, IIRB,
1128 CB);
1129 return &Fn;
1130}
1132 InstrumentationConfig &IConf,
1134 auto &Fn = cast<Function>(V);
1135 return getCI(&Ty, Fn.getName() == "main");
1136}
1137
1138/// UnreachableIO
1139///{
1141 InstrumentorIRBuilderTy &IIRB, ConfigTy *UserConfig) {
1142 if (UserConfig)
1143 Config = *UserConfig;
1144 addCommonArgs(IConf, IIRB.Ctx, Config.has(PassId));
1145 IConf.addChoice(*this, IIRB.Ctx);
1146}
1147///}
1148
1149/// AllocaIO
1150///{
1152 ConfigTy *UserConfig) {
1153 if (UserConfig)
1154 Config = *UserConfig;
1155
1157 if (!IsPRE && Config.has(PassAddress))
1158 IRTArgs.push_back(
1159 IRTArg(IIRB.PtrTy, "address", "The allocated memory address.",
1163 if (Config.has(PassSize))
1164 IRTArgs.push_back(IRTArg(
1165 IIRB.Int64Ty, "size", "The allocation size.",
1167 getSize, setSize));
1168 if (Config.has(PassAlignment))
1169 IRTArgs.push_back(IRTArg(IIRB.Int64Ty, "alignment",
1170 "The allocation alignment.", IRTArg::NONE,
1171 getAlignment));
1172
1173 addCommonArgs(IConf, IIRB.Ctx, Config.has(PassId));
1174 IConf.addChoice(*this, IIRB.Ctx);
1175}
1176
1179 auto &AI = cast<AllocaInst>(V);
1180 return IIRB.IRB.CreateAllocationSize(&Ty, &AI);
1181}
1182
1185 auto &AI = cast<AllocaInst>(V);
1186 const DataLayout &DL = AI.getDataLayout();
1187 auto *NewAI = IIRB.IRB.CreateAlloca(IIRB.IRB.getInt8Ty(),
1188 DL.getAllocaAddrSpace(), &NewV);
1189 NewAI->setAlignment(AI.getAlign());
1190 AI.replaceAllUsesWith(NewAI);
1191 IIRB.eraseLater(&AI);
1192 return NewAI;
1193}
1194
1197 return getCI(&Ty, cast<AllocaInst>(V).getAlign().value());
1198}
1199///}
1200
1202 ConfigTy *UserConfig) {
1203 if (UserConfig)
1204 Config = *UserConfig;
1205
1207 if (Config.has(PassPointer)) {
1208 IRTArgs.push_back(
1209 IRTArg(IIRB.PtrTy, "pointer", "The accessed pointer.",
1210 ((IsPRE && Config.has(ReplacePointer)) ? IRTArg::REPLACABLE
1211 : IRTArg::NONE),
1213 }
1214 if (Config.has(PassPointerAS)) {
1215 IRTArgs.push_back(IRTArg(IIRB.Int32Ty, "pointer_as",
1216 "The address space of the accessed pointer.",
1218 }
1219 if (Config.has(PassBasePointerInfo)) {
1220 IRTArgs.push_back(IRTArg(IIRB.PtrTy, "base_pointer_info",
1221 "The runtime provided base pointer info.",
1223 }
1224 if (Config.has(PassStoredValue)) {
1225 IRTArgs.push_back(
1226 IRTArg(getValueType(IIRB), "value", "The stored value.",
1229 : IRTArg::NONE),
1230 getValue));
1231 }
1232 if (Config.has(PassStoredValueSize)) {
1233 IRTArgs.push_back(IRTArg(IIRB.Int64Ty, "value_size",
1234 "The size of the stored value.", IRTArg::NONE,
1235 getValueSize));
1236 }
1237 if (Config.has(PassAlignment)) {
1238 IRTArgs.push_back(IRTArg(IIRB.Int64Ty, "alignment",
1239 "The known access alignment.", IRTArg::NONE,
1240 getAlignment));
1241 }
1242 if (Config.has(PassValueTypeId)) {
1243 IRTArgs.push_back(IRTArg(IIRB.Int32Ty, "value_type_id",
1244 "The type id of the stored value.", IRTArg::TYPEID,
1246 }
1247 if (Config.has(PassValueSubTypeId)) {
1248 IRTArgs.push_back(IRTArg(
1249 IIRB.Int32Ty, "value_sub_type_id",
1250 "The type id of the stored value (for arrays and vectors, or -1).",
1252 }
1253 if (Config.has(PassAtomicityOrdering)) {
1254 IRTArgs.push_back(IRTArg(IIRB.Int32Ty, "atomicity_ordering",
1255 "The atomicity ordering of the store.",
1257 }
1258 if (Config.has(PassSyncScopeId)) {
1259 IRTArgs.push_back(IRTArg(IIRB.Int8Ty, "sync_scope_id",
1260 "The sync scope id of the store.", IRTArg::NONE,
1262 }
1263 if (Config.has(PassIsVolatile)) {
1264 IRTArgs.push_back(IRTArg(IIRB.Int8Ty, "is_volatile",
1265 "Flag indicating a volatile store.", IRTArg::NONE,
1266 isVolatile));
1267 }
1268
1269 addCommonArgs(IConf, IIRB.Ctx, Config.has(PassId));
1270 IConf.addChoice(*this, IIRB.Ctx);
1271}
1272
1275 auto &SI = cast<StoreInst>(V);
1276 return SI.getPointerOperand();
1277}
1278
1281 auto &SI = cast<StoreInst>(V);
1282 SI.setOperand(SI.getPointerOperandIndex(), &NewV);
1283 return &SI;
1284}
1285
1288 auto &SI = cast<StoreInst>(V);
1289 return getCI(&Ty, SI.getPointerAddressSpace());
1290}
1291
1293 InstrumentationConfig &IConf,
1295 auto &SI = cast<StoreInst>(V);
1296 return IConf.getBasePointerInfo(*SI.getPointerOperand(), IIRB);
1297}
1298
1301 auto &SI = cast<StoreInst>(V);
1302 return SI.getValueOperand();
1303}
1304
1307 auto &SI = cast<StoreInst>(V);
1308 auto &DL = SI.getDataLayout();
1309 return getCI(&Ty, DL.getTypeStoreSize(SI.getValueOperand()->getType()));
1310}
1311
1314 auto &SI = cast<StoreInst>(V);
1315 return getCI(&Ty, SI.getAlign().value());
1316}
1317
1320 auto &SI = cast<StoreInst>(V);
1321 return getCI(&Ty, SI.getValueOperand()->getType()->getTypeID());
1322}
1323
1325 InstrumentationConfig &IConf,
1327 auto &SI = cast<StoreInst>(V);
1328 return getSubTypeID(*SI.getValueOperand()->getType(), Ty);
1329}
1330
1332 InstrumentationConfig &IConf,
1334 auto &SI = cast<StoreInst>(V);
1335 return getCI(&Ty, uint64_t(SI.getOrdering()));
1336}
1337
1340 auto &SI = cast<StoreInst>(V);
1341 return getCI(&Ty, uint64_t(SI.getSyncScopeID()));
1342}
1343
1346 auto &SI = cast<StoreInst>(V);
1347 return getCI(&Ty, SI.isVolatile());
1348}
1349
1351 ConfigTy *UserConfig) {
1353 if (UserConfig)
1354 Config = *UserConfig;
1355 if (Config.has(PassPointer)) {
1356 IRTArgs.push_back(
1357 IRTArg(IIRB.PtrTy, "pointer", "The accessed pointer.",
1358 ((IsPRE && Config.has(ReplacePointer)) ? IRTArg::REPLACABLE
1359 : IRTArg::NONE),
1361 }
1362 if (Config.has(PassPointerAS)) {
1363 IRTArgs.push_back(IRTArg(IIRB.Int32Ty, "pointer_as",
1364 "The address space of the accessed pointer.",
1366 }
1367 if (Config.has(PassBasePointerInfo)) {
1368 IRTArgs.push_back(IRTArg(IIRB.PtrTy, "base_pointer_info",
1369 "The runtime provided base pointer info.",
1371 }
1372 if (!IsPRE && Config.has(PassValue)) {
1373 IRTArgs.push_back(
1374 IRTArg(getValueType(IIRB), "value", "The loaded value.",
1375 Config.has(ReplaceValue)
1378 : IRTArg::NONE)
1379 : IRTArg::NONE,
1380 getValue, Config.has(ReplaceValue) ? replaceValue : nullptr));
1381 }
1382 if (Config.has(PassValueSize)) {
1383 IRTArgs.push_back(IRTArg(IIRB.Int64Ty, "value_size",
1384 "The size of the loaded value.", IRTArg::NONE,
1385 getValueSize));
1386 }
1387 if (Config.has(PassAlignment)) {
1388 IRTArgs.push_back(IRTArg(IIRB.Int64Ty, "alignment",
1389 "The known access alignment.", IRTArg::NONE,
1390 getAlignment));
1391 }
1392 if (Config.has(PassValueTypeId)) {
1393 IRTArgs.push_back(IRTArg(IIRB.Int32Ty, "value_type_id",
1394 "The type id of the loaded value.", IRTArg::TYPEID,
1396 }
1397 if (Config.has(PassValueSubTypeId)) {
1398 IRTArgs.push_back(IRTArg(
1399 IIRB.Int32Ty, "value_sub_type_id",
1400 "The sub type id of the loaded value (for arrays and vectors, or -1).",
1402 }
1403 if (Config.has(PassAtomicityOrdering)) {
1404 IRTArgs.push_back(IRTArg(IIRB.Int32Ty, "atomicity_ordering",
1405 "The atomicity ordering of the load.",
1407 }
1408 if (Config.has(PassSyncScopeId)) {
1409 IRTArgs.push_back(IRTArg(IIRB.Int8Ty, "sync_scope_id",
1410 "The sync scope id of the load.", IRTArg::NONE,
1412 }
1413 if (Config.has(PassIsVolatile)) {
1414 IRTArgs.push_back(IRTArg(IIRB.Int8Ty, "is_volatile",
1415 "Flag indicating a volatile load.", IRTArg::NONE,
1416 isVolatile));
1417 }
1418
1419 addCommonArgs(IConf, IIRB.Ctx, Config.has(PassId));
1420 IConf.addChoice(*this, IIRB.Ctx);
1421}
1422
1425 auto &LI = cast<LoadInst>(V);
1426 return LI.getPointerOperand();
1427}
1428
1431 auto &LI = cast<LoadInst>(V);
1432 LI.setOperand(LI.getPointerOperandIndex(), &NewV);
1433 return &LI;
1434}
1435
1438 auto &LI = cast<LoadInst>(V);
1439 return getCI(&Ty, LI.getPointerAddressSpace());
1440}
1441
1443 InstrumentationConfig &IConf,
1445 auto &LI = cast<LoadInst>(V);
1446 return IConf.getBasePointerInfo(*LI.getPointerOperand(), IIRB);
1447}
1448
1451 return &V;
1452}
1453
1456 auto &LI = cast<LoadInst>(V);
1457 auto &DL = LI.getDataLayout();
1458 return getCI(&Ty, DL.getTypeStoreSize(LI.getType()));
1459}
1460
1463 auto &LI = cast<LoadInst>(V);
1464 return getCI(&Ty, LI.getAlign().value());
1465}
1466
1469 auto &LI = cast<LoadInst>(V);
1470 return getCI(&Ty, LI.getType()->getTypeID());
1471}
1472
1474 InstrumentationConfig &IConf,
1476 auto &LI = cast<LoadInst>(V);
1477 return getSubTypeID(*LI.getType(), Ty);
1478}
1479
1481 InstrumentationConfig &IConf,
1483 auto &LI = cast<LoadInst>(V);
1484 return getCI(&Ty, uint64_t(LI.getOrdering()));
1485}
1486
1489 auto &LI = cast<LoadInst>(V);
1490 return getCI(&Ty, uint64_t(LI.getSyncScopeID()));
1491}
1492
1495 auto &LI = cast<LoadInst>(V);
1496 return getCI(&Ty, LI.isVolatile());
1497}
1498
1500 InstrumentorIRBuilderTy &IIRB, ConfigTy *UserConfig) {
1501 if (UserConfig)
1502 Config = *UserConfig;
1503 if (Config.has(PassPointer))
1504 IRTArgs.push_back(IRTArg(IIRB.PtrTy, "base_pointer",
1505 "The base pointer in question.",
1507 if (Config.has(PassPointerKind))
1508 IRTArgs.push_back(IRTArg(
1509 IIRB.Int32Ty, "base_pointer_kind",
1510 "The base pointer kind (argument, global, instruction, unknown).",
1512 addCommonArgs(IConf, IIRB.Ctx, Config.has(PassId));
1513 IConf.addChoice(*this, IIRB.Ctx);
1514}
1515
1517 InstrumentationConfig &IConf,
1519 if (isa<Argument>(V))
1520 return getCI(&Ty, 0);
1521 if (isa<GlobalValue>(V))
1522 return getCI(&Ty, 1);
1523 if (isa<Instruction>(V))
1524 return getCI(&Ty, 2);
1525 return getCI(&Ty, 3);
1526}
1527
1529 ConfigTy *UserConfig) {
1530 if (UserConfig)
1531 Config = *UserConfig;
1532
1533 if (Config.has(PassName))
1534 IRTArgs.push_back(IRTArg(IIRB.PtrTy, "module_name",
1535 "The module/translation unit name.",
1537 if (Config.has(PassTargetTriple))
1538 IRTArgs.push_back(IRTArg(IIRB.PtrTy, "target_triple", "The target triple.",
1540
1541 addCommonArgs(IConf, IIRB.Ctx, Config.has(PassId));
1542 IConf.addChoice(*this, IIRB.Ctx);
1543}
1546 // V is a constructor or destructor of the module we can place code in.
1547 auto &Fn = cast<Function>(V);
1548 return IConf.getGlobalString(Fn.getParent()->getName(), IIRB);
1549}
1551 InstrumentationConfig &IConf,
1553 // V is a constructor or destructor of the module we can place code in.
1554 auto &Fn = cast<Function>(V);
1555 return IConf.getGlobalString(Fn.getParent()->getTargetTriple().getTriple(),
1556 IIRB);
1557}
1558
1560 InstrumentorIRBuilderTy &IIRB, ConfigTy *UserConfig) {
1561 if (UserConfig)
1562 Config = *UserConfig;
1564 if (Config.has(PassAddress))
1565 IRTArgs.push_back(IRTArg(
1566 IIRB.PtrTy, "address",
1567 "The address of the global (replaceable for definitions).",
1570 if (Config.has(PassAS))
1571 IRTArgs.push_back(IRTArg(IIRB.Int32Ty, "address_space",
1572 "The address space of the global.", IRTArg::NONE,
1573 getAS));
1574 if (Config.has(PassDeclaredSize))
1575 IRTArgs.push_back(IRTArg(IIRB.Int64Ty, "declared_size",
1576 "The size of the declared type of the global.",
1578 if (Config.has(PassAlignment))
1579 IRTArgs.push_back(IRTArg(IIRB.Int64Ty, "alignment",
1580 "The allocation alignment.", IRTArg::NONE,
1581 getAlignment));
1582 if (Config.has(PassName))
1583 IRTArgs.push_back(IRTArg(IIRB.PtrTy, "name", "The name of the global.",
1585 if (Config.has(PassInitialValue))
1586 IRTArgs.push_back(IRTArg(
1587 IIRB.Int64Ty, "initial_value", "The initial value of the global.",
1590 if (Config.has(PassIsConstant))
1591 IRTArgs.push_back(IRTArg(IIRB.Int8Ty, "is_constant",
1592 "Flag to indicate constant globals.", IRTArg::NONE,
1593 isConstant));
1594 if (Config.has(PassIsDefinition))
1595 IRTArgs.push_back(IRTArg(IIRB.Int8Ty, "is_definition",
1596 "Flag to indicate global definitions.",
1598 addCommonArgs(IConf, IIRB.Ctx, Config.has(PassId));
1599 IConf.addChoice(*this, IIRB.Ctx);
1600}
1604 if (GV.getAddressSpace())
1605 return ConstantExpr::getAddrSpaceCast(&GV, IIRB.PtrTy);
1606 return &GV;
1607}
1609 InstrumentationConfig &IConf,
1612
1613 GlobalVariable *ShadowGV = nullptr;
1614 auto ShadowName = IConf.getRTName("shadow.", GV.getName());
1615 auto &DL = GV.getDataLayout();
1616 if (GV.isDeclaration()) {
1617 ShadowGV = new GlobalVariable(*GV.getParent(), GV.getType(), false,
1619 ShadowName, &GV, GV.getThreadLocalMode(),
1620 DL.getDefaultGlobalsAddressSpace());
1621 } else {
1622 ShadowGV = new GlobalVariable(
1623 *GV.getParent(), NewV.getType(), false, GV.getLinkage(),
1624 PoisonValue::get(NewV.getType()), ShadowName, &GV);
1625 IIRB.IRB.CreateStore(&NewV, ShadowGV);
1626 }
1627
1630 DenseMap<Value *, Instruction *> ConstToInstMap;
1632
1633 auto MakeInstForConst = [&](Use &U) {
1634 Instruction *&I = ConstToInstMap[U];
1635 if (I)
1636 return;
1637 if (U == &GV) {
1638 } else if (auto *CE = dyn_cast<ConstantExpr>(U)) {
1639 I = CE->getAsInstruction();
1640 }
1641 };
1642
1643 auto InsertConsts = [&](Instruction *UserI, Use &UserU) {
1645 auto *&Reload = ReloadMap[UserI->getFunction()];
1646 if (!Reload) {
1647 Reload = new LoadInst(
1648 GV.getType(), ShadowGV, GV.getName() + ".shadow_load",
1650 IIRB.NewInsts.insert({Reload, IIRB.Epoch});
1651 }
1652 Worklist.push_back({UserI, &UserU});
1653 while (!Worklist.empty()) {
1654 auto [I, U] = Worklist.pop_back_val();
1655 if (*U == &GV) {
1656 U->set(ReloadMap[I->getFunction()]);
1657 continue;
1658 }
1659 if (auto *CI = ConstToInstMap[*U]) {
1660 auto *CIClone = CI->clone();
1661 IIRB.NewInsts.insert({CIClone, IIRB.Epoch});
1662 if (auto *PHI = dyn_cast<PHINode>(I)) {
1663 auto *BB = PHI->getIncomingBlock(U->getOperandNo());
1664 CIClone->insertBefore(BB->getTerminator()->getIterator());
1665 } else {
1666 CIClone->insertBefore(I->getIterator());
1667 }
1668 U->set(CIClone);
1669 for (auto &CICUse : CIClone->operands()) {
1670 Worklist.push_back({CIClone, &CICUse});
1671 }
1672 }
1673 }
1674 };
1675
1676 while (!Worklist.empty()) {
1677 Use *U = Worklist.pop_back_val();
1678 if (!Done.insert(U).second)
1679 continue;
1680 MakeInstForConst(*U);
1681 auto *I = dyn_cast<Instruction>(U->getUser());
1682 if (!I) {
1683 append_range(Worklist, make_pointer_range(U->getUser()->uses()));
1684 continue;
1685 }
1686 if (IIRB.NewInsts.lookup(I) == IIRB.Epoch)
1687 continue;
1689 continue;
1690 if (auto *II = dyn_cast<IntrinsicInst>(I))
1691 if (II->getIntrinsicID() == Intrinsic::eh_typeid_for)
1692 continue;
1693 if (I->getParent())
1694 InsertConsts(I, *U);
1695 }
1696
1697 for (auto &It : ConstToInstMap)
1698 if (It.second)
1699 It.second->deleteValue();
1700
1701 return &V;
1702}
1706 return getCI(&Ty, GV.getAddressSpace());
1707}
1709 InstrumentationConfig &IConf,
1712 MaybeAlign Alignment = GV.getAlign();
1713 return getCI(&Ty, Alignment ? Alignment->value() : 0);
1714}
1716 InstrumentationConfig &IConf,
1719 auto &DL = GV.getDataLayout();
1720 return getCI(&Ty, DL.getTypeAllocSize(GV.getValueType()));
1721}
1723 InstrumentationConfig &IConf,
1726 return IConf.getGlobalString(GV.getName(), IIRB);
1727}
1738 return getCI(&Ty, GV.isConstant());
1739}
1741 InstrumentationConfig &IConf,
1744 return getCI(&Ty, !GV.isDeclaration());
1745}
1746
1747/// CastIO
1748/// {
1750 ConfigTy *UserConfig) {
1751 if (UserConfig)
1752 Config = *UserConfig;
1754 if (Config.has(PassInput))
1755 IRTArgs.push_back(
1756 IRTArg(IIRB.Int64Ty, "input", "Input value of the cast.",
1759 : IRTArg::NONE),
1760 getInput));
1761 if (Config.has(PassInputTypeId))
1762 IRTArgs.push_back(IRTArg(IIRB.Int32Ty, "input_type_id",
1763 "The type id of the input value.", IRTArg::TYPEID,
1765 if (Config.has(PassInputSubTypeId))
1766 IRTArgs.push_back(IRTArg(
1767 IIRB.Int32Ty, "input_sub_type_id",
1768 "The sub type id of the input value (for arrays and vectors, or -1).",
1770 if (Config.has(PassInputSize))
1771 IRTArgs.push_back(IRTArg(IIRB.Int32Ty, "input_size",
1772 "The size of the input value.", IRTArg::NONE,
1773 getInputSize));
1774 if (!IsPRE && Config.has(PassResult))
1775 IRTArgs.push_back(
1776 IRTArg(IIRB.Int64Ty, "result", "Result of the cast.",
1779 : IRTArg::NONE),
1780 getValue, Config.has(ReplaceResult) ? replaceValue : nullptr));
1781 if (Config.has(PassResultTypeId))
1782 IRTArgs.push_back(IRTArg(IIRB.Int32Ty, "result_type_id",
1783 "The type id of the result value.", IRTArg::TYPEID,
1785 if (Config.has(PassResultSubTypeId))
1786 IRTArgs.push_back(IRTArg(
1787 IIRB.Int32Ty, "result_sub_type_id",
1788 "The sub type id of the result value (for arrays and vectors, or -1).",
1790 if (Config.has(PassResultSize))
1791 IRTArgs.push_back(IRTArg(IIRB.Int32Ty, "result_size",
1792 "The size of the result value.", IRTArg::NONE,
1793 getResultSize));
1794 if (Config.has(PassOpcode))
1795 IRTArgs.push_back(IRTArg(IIRB.Int32Ty, "opcode",
1796 "The opcode of the cast instruction.",
1798
1799 addCommonArgs(IConf, IIRB.Ctx, Config.has(PassId));
1800 IConf.addChoice(*this, IIRB.Ctx);
1801}
1802
1805 auto &CI = cast<CastInst>(V);
1806 return CI.getOperand(0);
1807}
1808
1811 auto &CI = cast<CastInst>(V);
1812 return getCI(&Ty, CI.getSrcTy()->getTypeID());
1813}
1814
1816 InstrumentationConfig &IConf,
1818 auto &CI = cast<CastInst>(V);
1819 return getSubTypeID(*CI.getSrcTy(), Ty);
1820}
1821
1824 auto &CI = cast<CastInst>(V);
1825 auto &DL = CI.getDataLayout();
1826 return getCI(&Ty, DL.getTypeStoreSize(CI.getSrcTy()));
1827}
1828
1831 auto &CI = cast<CastInst>(V);
1832 return getCI(&Ty, CI.getDestTy()->getTypeID());
1833}
1834
1836 InstrumentationConfig &IConf,
1838 auto &CI = cast<CastInst>(V);
1839 return getSubTypeID(*CI.getDestTy(), Ty);
1840}
1841
1844 auto &CI = cast<CastInst>(V);
1845 auto &DL = CI.getDataLayout();
1846 return getCI(&Ty, DL.getTypeStoreSize(CI.getDestTy()));
1847}
1848///}
1849
1852 auto &I = cast<Instruction>(V);
1853 uint64_t Flag = NUMERIC_FLAG_NONE;
1854
1855 switch (I.getOpcode()) {
1856 case Instruction::Add:
1857 case Instruction::Sub:
1858 case Instruction::Mul:
1859 case Instruction::Shl:
1860 if (I.hasNoSignedWrap())
1862 if (I.hasNoUnsignedWrap())
1864 break;
1865 case Instruction::FAdd:
1866 case Instruction::FSub:
1867 case Instruction::FMul:
1868 case Instruction::FDiv:
1869 case Instruction::FNeg:
1870 if (I.hasNoNaNs())
1872 if (I.hasNoInfs())
1874 if (I.hasNoSignedZeros())
1876 break;
1877 case Instruction::AShr:
1878 case Instruction::LShr:
1879 case Instruction::SDiv:
1880 case Instruction::UDiv:
1881 if (I.isExact())
1882 Flag |= NUMERIC_FLAG_IS_EXACT;
1883 break;
1884 }
1885
1886 if (auto *DI = dyn_cast<PossiblyDisjointInst>(&V))
1887 if (DI->isDisjoint())
1889
1890 return getCI(&Ty, Flag);
1891}
1892
1901
1903 InstrumentorIRBuilderTy &IIRB, ConfigTy *UserConfig) {
1904 if (UserConfig)
1905 Config = UserConfig;
1907 const auto ValArgOpts =
1910 if (Config.has(PassTypeId))
1911 IRTArgs.push_back(IRTArg(IIRB.Int32Ty, "type_id",
1912 "The operation's type id.", IRTArg::TYPEID,
1913 getTypeId));
1914 if (Config.has(PassSubTypeId))
1915 IRTArgs.push_back(
1916 IRTArg(IIRB.Int32Ty, "sub_type_id",
1917 "The operation's sub type id (for arrays and vectors, or -1).",
1919 if (Config.has(PassSize))
1920 IRTArgs.push_back(IRTArg(IIRB.Int32Ty, "size", "The operation's type size.",
1922 if (Config.has(PassOpcode))
1923 IRTArgs.push_back(IRTArg(IIRB.Int32Ty, "opcode", "The instruction opcode.",
1925 if (Config.has(PassLeft))
1926 IRTArgs.push_back(IRTArg(IIRB.Int64Ty, "left",
1927 "The operation's left operand.", ValArgOpts,
1929 if (Config.has(PassRight))
1930 IRTArgs.push_back(IRTArg(IIRB.Int64Ty, "right",
1931 "The operation's right operand. This value is "
1932 "poison for unary operations.",
1933 ValArgOpts, getRightOperand));
1934 if (!IsPRE && Config.has(PassResult))
1935 IRTArgs.push_back(
1936 IRTArg(IIRB.Int64Ty, "result", "Result of the operation.",
1937 IRTArg::REPLACABLE | ValArgOpts, getValue,
1938 Config.has(ReplaceResult) ? replaceValue : nullptr));
1939 if (Config.has(PassFlags))
1940 IRTArgs.push_back(
1941 IRTArg(IIRB.Int64Ty, "flags",
1942 "A bitmask value signaling which instruction flags are present.",
1944 addCommonArgs(IConf, IIRB.Ctx, Config.has(PassId));
1945 addFlagNames();
1946 IConf.addChoice(*this, IIRB.Ctx);
1947}
1948
1950 InstrumentationConfig &IConf,
1952 auto &I = cast<Instruction>(V);
1953 return getCI(&Ty, I.getOperand(0)->getType()->getTypeID());
1954}
1955
1957 InstrumentationConfig &IConf,
1959 auto &I = cast<Instruction>(V);
1960 auto &DL = I.getDataLayout();
1961 return getCI(&Ty, DL.getTypeStoreSize(I.getOperand(0)->getType()));
1962}
1963
1966 auto *CI = dyn_cast<CmpInst>(&V);
1967 return getCI(&Ty, CI->getPredicate());
1968}
1969
1976
1979 auto &I = cast<Instruction>(V);
1980 uint64_t Flag = NUMERIC_FLAG_NONE;
1981
1982 switch (I.getOpcode()) {
1983 case Instruction::ICmp:
1984 if (dyn_cast<ICmpInst>(&V)->hasSameSign())
1985 Flag |= COMPARE_FLAG_SAMESIGN;
1986 break;
1987 case Instruction::FCmp:
1988 if (I.hasNoNaNs())
1990 if (I.hasNoInfs())
1992 if (I.hasNoSignedZeros())
1994 break;
1995 }
1996
1997 return getCI(&Ty, Flag);
1998}
1999
2001 InstrumentorIRBuilderTy &IIRB, ConfigTy *UserConfig) {
2002 if (UserConfig)
2003 Config = UserConfig;
2005 const auto OperandArgOpts =
2008 if (Config.has(PassOpTypeId))
2009 IRTArgs.push_back(IRTArg(IIRB.Int32Ty, "operand_type_id",
2010 "The operand type id.", IRTArg::NONE,
2012 if (Config.has(PassOpSize))
2013 IRTArgs.push_back(IRTArg(IIRB.Int32Ty, "operand_size",
2014 "The operand type size.", IRTArg::NONE,
2016 if (Config.has(PassOpcode))
2017 IRTArgs.push_back(IRTArg(IIRB.Int32Ty, "opcode", "The instruction opcode.",
2019 if (Config.has(PassPredicate))
2020 IRTArgs.push_back(IRTArg(IIRB.Int32Ty, "predicate",
2021 "The comparison predicate ID.", IRTArg::NONE,
2022 getPredicate));
2023 if (Config.has(PassLeft))
2024 IRTArgs.push_back(IRTArg(IIRB.Int64Ty, "left",
2025 "The comparison's left operand.", OperandArgOpts,
2027 if (Config.has(PassRight))
2028 IRTArgs.push_back(IRTArg(IIRB.Int64Ty, "right",
2029 "The comparison's right operand.", OperandArgOpts,
2031 if (!IsPRE && Config.has(PassResultSize))
2032 IRTArgs.push_back(IRTArg(IIRB.Int32Ty, "result_type_id",
2033 "The result value's type ID.", IRTArg::NONE,
2034 getTypeId));
2035 if (!IsPRE && Config.has(PassResultSize))
2036 IRTArgs.push_back(IRTArg(IIRB.Int32Ty, "result_size",
2037 "Size of the result value.", IRTArg::NONE,
2038 getTypeSize));
2039 if (!IsPRE && Config.has(PassResult))
2040 IRTArgs.push_back(
2041 IRTArg(IIRB.Int64Ty, "result", "Result of the operation.",
2044 : IRTArg::NONE),
2045 getValue, Config.has(ReplaceResult) ? replaceValue : nullptr));
2046 if (Config.has(PassFlags))
2047 IRTArgs.push_back(
2048 IRTArg(IIRB.Int64Ty, "flags",
2049 "A bitmask value signaling which instruction flags are present.",
2051 addFlagNames();
2052 addCommonArgs(IConf, IIRB.Ctx, Config.has(PassId));
2053 IConf.addChoice(*this, IIRB.Ctx);
2054}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file defines the StringMap class.
uint64_t uint64_t
Rewrite undef for PHI
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static cl::opt< ITMode > IT(cl::desc("IT block support"), cl::Hidden, cl::init(DefaultIT), cl::values(clEnumValN(DefaultIT, "arm-default-it", "Generate any type of IT block"), clEnumValN(RestrictedIT, "arm-restrict-it", "Disallow complex IT blocks")))
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
post inline ee instrument
#define _
static MaybeAlign getAlign(Value *Ptr)
Module.h This file contains the declarations for the Module class.
This header defines various interfaces for pass management in LLVM.
@ COMPARE_FLAG_HAS_NO_NANS
@ COMPARE_FLAG_HAS_NO_INFS
@ COMPARE_FLAG_HAS_NO_SIGNED_ZEROS
@ NUMERIC_FLAG_NO_SIGNED_WRAP
@ NUMERIC_FLAG_NO_UNSIGNED_WRAP
@ NUMERIC_FLAG_HAS_NO_SIGNED_ZEROS
@ NUMERIC_FLAG_HAS_NO_INFS
@ NUMERIC_FLAG_HAS_NO_NANS
@ NUMERIC_FLAG_IS_DISJOINT
static void readValuePack(const Range &R, Value &Pack, InstrumentorIRBuilderTy &IIRB, function_ref< void(int, Value *)> SetterCB)
static constexpr Value * getValue(Ty &ValueOrUse)
static Value * createValuePack(const Range &R, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static Regex createRegex(StringRef Str, StringRef Name, LLVMContext &Ctx)
#define I(x, y, z)
Definition MD5.cpp:57
This file contains the declarations for metadata subclasses.
#define T
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
uint64_t IntrinsicInst * II
ModuleAnalysisManager MAM
if(PassOpts->AAPipeline)
This file builds on the ADT/GraphTraits.h file to build a generic graph post order iterator.
This file contains some templates that are useful if you are working with the STL at all.
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
This file contains some functions that are useful when dealing with strings.
#define LLVM_DEBUG(...)
Definition Debug.h:119
Defines the virtual file system interface vfs::FileSystem.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
bool empty() const
Check if the array is empty.
Definition ArrayRef.h:136
static LLVM_ABI ArrayType * get(Type *ElementType, uint64_t NumElements)
This static method is the primary way to construct an ArrayType.
static LLVM_ABI Attribute get(LLVMContext &Context, AttrKind Kind, uint64_t Val=0)
Return a uniquified Attribute object.
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
Definition BasicBlock.h:206
LLVM_ABI const_iterator getFirstNonPHIOrAlloca() const
Returns an iterator to the first instruction in this block that is not a PHINode, a static alloca,...
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction; assumes that the block is well-formed.
Definition BasicBlock.h:237
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)
static LLVM_ABI ConstantPointerNull * get(PointerType *T)
Static factory methods - Return objects of the specified value.
static LLVM_ABI Constant * get(StructType *T, ArrayRef< Constant * > V)
This is an important base class in LLVM.
Definition Constant.h:44
static LLVM_ABI Constant * getAllOnesValue(Type *Ty)
static LLVM_ABI Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
A parsed version of the target data layout string in and methods for querying it.
Definition DataLayout.h:64
LLVM_ABI TypeSize getTypeAllocSize(Type *Ty) const
Returns the offset in bytes between successive objects of the specified type, including alignment pad...
Diagnostic information for IR instrumentation reporting.
Class to represent function types.
static LLVM_ABI FunctionType * get(Type *Result, ArrayRef< Type * > Params, bool isVarArg)
This static method is the primary way of constructing a FunctionType.
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
Definition Function.h:169
const BasicBlock & getEntryBlock() const
Definition Function.h:803
const DataLayout & getDataLayout() const
Get the data layout of the module this function belongs to.
Definition Function.cpp:356
iterator_range< arg_iterator > args()
Definition Function.h:886
arg_iterator arg_begin()
Definition Function.h:862
bool isIntrinsic() const
isIntrinsic - Returns true if the function's name starts with "llvm.".
Definition Function.h:252
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
Definition Function.cpp:352
size_t arg_size() const
Definition Function.h:895
Argument * getArg(unsigned i) const
Definition Function.h:880
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
Definition Function.cpp:731
StringRef getSection() const
Get the custom section of this global if it has one.
LLVM_ABI bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
Definition Globals.cpp:408
LinkageTypes getLinkage() const
ThreadLocalMode getThreadLocalMode() const
unsigned getAddressSpace() const
Module * getParent()
Get the module that this global value is contained inside of...
PointerType * getType() const
Global values are always pointers.
LLVM_ABI const DataLayout & getDataLayout() const
Get the data layout of the module this global belongs to.
Definition Globals.cpp:205
@ PrivateLinkage
Like Internal, but omit from symbol table.
Definition GlobalValue.h:61
@ InternalLinkage
Rename collisions when linking (static functions).
Definition GlobalValue.h:60
@ WeakODRLinkage
Same, but only replaced by something equivalent.
Definition GlobalValue.h:58
Type * getValueType() const
const Constant * getInitializer() const
getInitializer - Return the initializer for this global variable.
bool hasInitializer() const
Definitions have initializers, declarations don't.
MaybeAlign getAlign() const
Returns the alignment of the given variable.
bool isConstant() const
If the value is a global constant, its value is immutable throughout the runtime execution of the pro...
LLVM_ABI const Function * getFunction() const
Return the function this instruction belongs to.
LLVM_ABI 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:76
LLVM_ABI void diagnose(const DiagnosticInfo &DI)
Report a message to the currently installed diagnostic handler.
static LLVM_ABI bool linkModules(Module &Dest, std::unique_ptr< Module > Src, unsigned Flags=Flags::None, std::function< void(Module &, const StringSet<> &)> InternalizeCallback={})
This function links two modules together, with the resulting Dest module modified to be the composite...
An instruction for reading from memory.
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
Definition Metadata.h:1579
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:68
const Triple & getTargetTriple() const
Get the target triple which is a string describing the target host.
Definition Module.h:328
LLVMContext & getContext() const
Get the global data context.
Definition Module.h:332
size_t global_size() const
Definition Module.h:799
StringRef getName() const
Get a short "name" for the module.
Definition Module.h:316
iterator_range< global_iterator > globals()
Definition Module.h:802
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
A set of analyses that are preserved following a run of a transformation pass.
Definition Analysis.h:112
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
Definition Analysis.h:115
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition Analysis.h:118
LLVM_ABI bool isValid(std::string &Error) const
isValid - returns the error encountered during regex compilation, if any.
Definition Regex.cpp:70
LLVM_ABI bool match(StringRef String, SmallVectorImpl< StringRef > *Matches=nullptr, std::string *Error=nullptr) const
matches - Match the regex against a given String.
Definition Regex.cpp:84
StringRef getMessage() const
Definition SourceMgr.h:338
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
void reserve(size_type N)
iterator insert(iterator I, T &&Elt)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition StringRef.h:258
Class to represent struct types.
static LLVM_ABI StructType * get(LLVMContext &Context, ArrayRef< Type * > Elements, bool isPacked=false)
This static method is the primary way to create a literal StructType.
Definition Type.cpp:467
const std::string & getTriple() const
Definition Triple.h:583
bool isAMDGPU() const
Definition Triple.h:999
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition Twine.h:82
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
bool isVectorTy() const
True if this is an instance of VectorType.
Definition Type.h:283
bool isPointerTy() const
True if this is an instance of PointerType.
Definition Type.h:277
bool isAggregateType() const
Return true if the type is an aggregate type.
Definition Type.h:314
bool isFloatingPointTy() const
Return true if this is one of the floating-point types.
Definition Type.h:186
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition Type.h:252
A Use represents the edge between a Value definition and its users.
Definition Use.h:35
LLVM Value Representation.
Definition Value.h:75
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:257
LLVM_ABI bool replaceUsesWithIf(Value *New, llvm::function_ref< bool(Use &U)> ShouldReplace)
Go through the uses list for this definition and make each use point to "V" if the callback ShouldRep...
Definition Value.cpp:556
iterator_range< use_iterator > uses()
Definition Value.h:382
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
Definition Value.cpp:314
An efficient, type-erasing, non-owning reference to a callable.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
LLVM_ABI void writeConfigToJSON(InstrumentationConfig &IConf, StringRef OutputFile, LLVMContext &Ctx)
Write the configuration in /p IConf to the file with path OutputFile.
LLVM_ABI bool readConfigPathsFile(StringRef InputFile, cl::list< std::string > &Configs, LLVMContext &Ctx, vfs::FileSystem &FS)
Read the configuration paths from the file with path InputFile into Configs.
LLVM_ABI bool readConfigFromJSON(InstrumentationConfig &IConf, StringRef InputFile, LLVMContext &Ctx, vfs::FileSystem &FS)
Read the configuration from the file with path InputFile into /p IConf.
LLVM_ABI void printRuntimeStub(const InstrumentationConfig &IConf, StringRef StubRuntimeName, LLVMContext &Ctx)
Print a runtime stub file with the implementation of the instrumentation runtime functions correspond...
LLVM_ABI IntrusiveRefCntPtr< FileSystem > getRealFileSystem()
Gets an vfs::FileSystem for the 'real' file system, as seen by the operating system.
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:577
LLVM_ABI void PromoteMemToReg(ArrayRef< AllocaInst * > Allocas, DominatorTree &DT, AssumptionCache *AC=nullptr)
Promote the specified list of alloca instructions into scalar registers, inserting PHI nodes as appro...
RelativeUniformCounterPtr Values
Definition InstrProf.h:91
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
Definition STLExtras.h:2570
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
@ Done
Definition Threading.h:60
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
Definition STLExtras.h:2224
LLVM_ABI InlineResult InlineFunction(CallBase &CB, InlineFunctionInfo &IFI, bool MergeAttributes=false, AAResults *CalleeAAR=nullptr, bool InsertLifetime=true, bool TrackInlineHistory=false, Function *ForwardVarArgsTo=nullptr, OptimizationRemarkEmitter *ORE=nullptr)
This function inlines the called function into the basic block of the caller.
LLVM_ABI bool isAllocaPromotable(const AllocaInst *AI)
Return true if this alloca is legal for promotion.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
Definition InstrProf.h:143
const IPOOptions & getIPOOptions(const LLVMContext &C)
Definition IPOOptions.h:36
constexpr uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition Alignment.h:149
iterator_range< filter_iterator< detail::IterOfRange< RangeT >, PredicateT > > make_filter_range(RangeT &&Range, PredicateT Pred)
Convenience function that takes a range of elements and a predicate, and return a new filter_iterator...
Definition STLExtras.h:552
LLVM_ABI const Value * getUnderlyingObjectAggressive(const Value *V, bool MustPreserveProvenance=false)
Like getUnderlyingObject(), but will try harder to find a single underlying object.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
ArrayRef(const T &OneElt) -> ArrayRef< T >
LLVM_ABI void appendToGlobalCtors(Module &M, Function *F, int Priority, Constant *Data=nullptr)
Append F to the list of global ctors of module M with the given Priority.
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
void erase_if(Container &C, UnaryPredicate P)
Provide a container algorithm similar to C++ Library Fundamentals v2's erase_if which is equivalent t...
Definition STLExtras.h:2208
iterator_range< pointer_iterator< WrappedIteratorT > > make_pointer_range(RangeT &&Range)
Definition iterator.h:368
LLVM_ABI std::unique_ptr< Module > parseIRFile(StringRef Filename, SMDiagnostic &Err, LLVMContext &Context, ParserCallbacks Callbacks={}, AsmParserContext *ParserContext=nullptr)
If the given file holds a bitcode image, return a Module for it.
Definition IRReader.cpp:94
LLVM_ABI void appendToGlobalDtors(Module &M, Function *F, int Priority, Constant *Data=nullptr)
Same as appendToGlobalCtors(), but for global dtors.
DEMANGLE_ABI std::string demangle(std::string_view MangledName)
Attempt to demangle a string using different demangling schemes.
Definition Demangle.cpp:21
LLVM_ABI bool verifyModule(const Module &M, raw_ostream *OS=nullptr, bool *BrokenDebugInfo=nullptr)
Check a module for errors.
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.
Definition MIRParser.h:39
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
Definition Alignment.h:111
static void populate(InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
LLVM_ABI void init(InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB, ConfigTy *UserConfig=nullptr)
}
BaseConfigTy< ConfigKind > ConfigTy
static LLVM_ABI Value * getSize(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static LLVM_ABI Value * setSize(Value &V, Value &NewV, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static LLVM_ABI Value * getAlignment(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static LLVM_ABI std::unique_ptr< BaseConfigurationOption > createStringListOption(InstrumentationConfig &IC, StringRef Name, StringRef Description, ArrayRef< StringRef > DefaultValue)
Create a string-list option with Name name, Description description and DefaultValue as string-list d...
static LLVM_ABI 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...
static LLVM_ABI 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...
static LLVM_ABI Value * getOpcode(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static LLVM_ABI Value * getTypeId(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static LLVM_ABI Value * getRightOperand(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static LLVM_ABI Value * getSubTypeId(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static LLVM_ABI Value * getTypeSize(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static LLVM_ABI Value * getLeftOperand(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static void populate(InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static LLVM_ABI Value * getPointerKind(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static Value * setValueNoop(Value &V, Value &NewV, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
This is necessary to produce a return value that can be used by other IOs.
BaseConfigTy< ConfigKind > ConfigTy
LLVM_ABI void init(InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB, ConfigTy *UserConfig=nullptr)
LLVM_ABI void init(InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB, ConfigTy *UserConfig=nullptr)
CastIO {.
static LLVM_ABI Value * getResultTypeId(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static LLVM_ABI Value * getInputSize(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static void populate(InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static LLVM_ABI Value * getResultSize(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static LLVM_ABI Value * getResultSubTypeId(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static LLVM_ABI Value * getInput(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static LLVM_ABI Value * getInputSubTypeId(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
BaseConfigTy< ConfigKind > ConfigTy
static LLVM_ABI Value * getInputTypeId(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static LLVM_ABI Value * getFlags(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static LLVM_ABI Value * getOperandSize(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static void populate(InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static LLVM_ABI Value * getOperandTypeId(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
BaseConfigTy< ConfigKind > ConfigTy
static LLVM_ABI Value * getPredicate(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
LLVM_ABI void init(InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB, ConfigTy *UserConfig=nullptr)
llvm::instrumentor::FunctionIO::ConfigTy Config
static void populate(InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
LLVM_ABI Value * setArguments(Value &V, Value &NewV, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static LLVM_ABI Value * getFunctionAddress(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static LLVM_ABI Value * isMainFunction(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
LLVM_ABI Value * getArguments(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
LLVM_ABI Value * getNumArguments(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static LLVM_ABI Value * getFunctionName(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
LLVM_ABI void init(InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB, ConfigTy *UserConfig=nullptr)
FunctionIO {.
static LLVM_ABI Value * setAddress(Value &V, Value &NewV, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
LLVM_ABI void init(InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB, ConfigTy *UserConfig=nullptr)
static LLVM_ABI Value * getAS(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static LLVM_ABI Value * getAlignment(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static LLVM_ABI Value * getInitialValue(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static LLVM_ABI Value * isDefinition(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static LLVM_ABI Value * getDeclaredSize(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static LLVM_ABI Value * getSymbolName(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static void populate(InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static LLVM_ABI Value * getAddress(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
BaseConfigTy< ConfigKind > ConfigTy
static LLVM_ABI Value * isConstant(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
bool isReplacable(IRTArg &IRTA) const
Return whether the IRTA argument can be replaced.
LLVM_ABI 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.
LLVM_ABI 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.
LLVM_ABI FunctionType * createLLVMSignature(InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB, const DataLayout &DL, bool ForceIndirection)
Create the type of the instrumentation function.
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.
Helper that represent the caches for instrumentation call arguments.
DenseMap< std::tuple< unsigned, StringRef, StringRef >, Value * > DirectArgCache
A cache for direct and indirect arguments.
DenseMap< std::tuple< unsigned, StringRef, StringRef >, Value * > IndirectArgCache
The class that contains the configuration for the instrumentor.
virtual void populate(InstrumentorIRBuilderTy &IIRB)
Populate the instrumentation opportunities.
std::unique_ptr< BaseConfigurationOption > InlineRuntimeEagerly
void addChoice(InstrumentationOpportunity &IO, LLVMContext &Ctx)
Register instrumentation opportunity IO.
Constant * getGlobalString(StringRef S, InstrumentorIRBuilderTy &IIRB)
DenseMap< Value *, Value * > UnderlyingObjsMap
Map to remember underlying objects for pointers.
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...
DenseMap< std::pair< Value *, Function * >, Value * > BasePointerInfoMap
Map to remember base pointer info for values in a specific function.
EnumeratedArray< MapVector< StringRef, InstrumentationOpportunity * >, InstrumentationLocation::KindTy > IChoices
The map registered instrumentation opportunities.
std::unique_ptr< BaseConfigurationOption > GPUEnabled
std::unique_ptr< BaseConfigurationOption > RuntimeBitcodes
DenseMap< Constant *, GlobalVariable * > ConstantGlobalsCache
Mapping from constants to globals with the constant as initializer.
Value * getBasePointerInfo(Value &V, InstrumentorIRBuilderTy &IIRB)
Return the base pointer info for V.
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.
std::unique_ptr< BaseConfigurationOption > FunctionRegex
std::unique_ptr< BaseConfigurationOption > TargetRegex
bool isPRE() const
Return whether the instrumentation location is before the event occurs.
Base class for instrumentation opportunities.
InstrumentationLocation::KindTy getLocationKind() const
Get the location kind of the instrumentation opportunity.
static LLVM_ABI Value * getIdPre(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
Get the opportunity identifier for the pre and post positions.
static LLVM_ABI 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)
}
static LLVM_ABI Value * getIdPost(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static Value * getValue(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static LLVM_ABI Value * replaceValue(Value &V, Value &NewV, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
StringMap< int32_t > FlagNames
Flag names and their integer bitmask values.
virtual StringRef getName() const =0
Get the name of the instrumentation opportunity.
SmallVector< IRTArg > IRTArgs
The list of possible arguments for the instrumentation runtime function.
void addCommonArgs(InstrumentationConfig &IConf, LLVMContext &Ctx, bool PassId)
}
An IR builder augmented with extra information for the instrumentor pass.
IRBuilder< ConstantFolder, IRBuilderCallbackInserter > IRB
The underlying IR builder with insertion callback.
unsigned Epoch
The current epoch number.
AllocaInst * getAlloca(Function *Fn, Type *Ty)
Get a temporary alloca to communicate (large) values with the runtime.
void returnAllocas()
Return the temporary allocas.
DenseMap< Instruction *, unsigned > NewInsts
A mapping from instrumentation instructions to the epoch they have been created.
DenseMap< std::pair< Function *, unsigned >, AllocaListTy * > AllocaMap
Map that holds a list of currently available allocas for a function and alloca size.
void eraseLater(Instruction *I)
Save instruction I to be erased later.
static LLVM_ABI Value * getValueSize(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static LLVM_ABI Value * getSyncScopeId(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static LLVM_ABI Value * getAtomicityOrdering(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
virtual Type * getValueType(InstrumentorIRBuilderTy &IIRB) const
}
static LLVM_ABI Value * getValueSubTypeId(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static LLVM_ABI Value * getValue(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static LLVM_ABI Value * getAlignment(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static LLVM_ABI 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 LLVM_ABI Value * isVolatile(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static LLVM_ABI Value * getBasePointerInfo(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static LLVM_ABI Value * setPointer(Value &V, Value &NewV, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
BaseConfigTy< ConfigKind > ConfigTy
static LLVM_ABI Value * getPointerAS(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static void populate(InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
}
static LLVM_ABI Value * getValueTypeId(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
LLVM_ABI void init(InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB, ConfigTy *UserConfig=nullptr)
Initialize the load opportunity using the instrumentation config IConf and the user config UserConfig...
static LLVM_ABI Value * getModuleName(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static void populate(InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static LLVM_ABI Value * getTargetTriple(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
LLVM_ABI void init(InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB, ConfigTy *UserConfig=nullptr)
BaseConfigTy< ConfigKind > ConfigTy
static LLVM_ABI Value * getFlags(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
}
LLVM_ABI void init(InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB, ConfigTy *UserConfig=nullptr)
static void populate(InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
BaseConfigTy< ConfigKind > ConfigTy
static LLVM_ABI 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 LLVM_ABI Value * getValueTypeId(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
virtual Type * getValueType(InstrumentorIRBuilderTy &IIRB) const
}
static LLVM_ABI Value * getSyncScopeId(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static LLVM_ABI Value * getPointerAS(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static LLVM_ABI Value * getAlignment(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static LLVM_ABI Value * getValue(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static LLVM_ABI Value * setPointer(Value &V, Value &NewV, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static LLVM_ABI Value * isVolatile(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static LLVM_ABI Value * getValueSize(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static LLVM_ABI Value * getValueSubTypeId(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
BaseConfigTy< ConfigKind > ConfigTy
LLVM_ABI void init(InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB, ConfigTy *UserConfig=nullptr)
Initialize the store opportunity using the instrumentation config IConf and the user config UserConfi...
static LLVM_ABI Value * getBasePointerInfo(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static LLVM_ABI Value * getAtomicityOrdering(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
static void populate(InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
LLVM_ABI void init(InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB, ConfigTy *UserConfig=nullptr)
UnreachableIO {.
BaseConfigTy< ConfigKind > ConfigTy