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
18
20#include "llvm/ADT/STLExtras.h"
24#include "llvm/ADT/StringMap.h"
25#include "llvm/ADT/iterator.h"
28#include "llvm/IR/Constant.h"
29#include "llvm/IR/Constants.h"
30#include "llvm/IR/DataLayout.h"
33#include "llvm/IR/Dominators.h"
34#include "llvm/IR/Function.h"
35#include "llvm/IR/IRBuilder.h"
36#include "llvm/IR/InstrTypes.h"
37#include "llvm/IR/Instruction.h"
40#include "llvm/IR/Intrinsics.h"
41#include "llvm/IR/LLVMContext.h"
42#include "llvm/IR/Metadata.h"
43#include "llvm/IR/Module.h"
44#include "llvm/IR/PassManager.h"
45#include "llvm/IR/Verifier.h"
47#include "llvm/Linker/Linker.h"
50#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 an output JSON file to write the configuration.
74static cl::opt<std::string> OutputConfigFile(
75 "instrumentor-write-config-file",
77 "Write the instrumentor configuration into the specified JSON file"),
78 cl::init(""));
79
80/// The user option to specify input JSON files to read the configuration from.
82 ConfigFiles("instrumentor-read-config-files",
83 cl::desc("Read the instrumentor configuration from the "
84 "specified JSON files (comma separated)"),
86
87/// The user option to specify an input file to read the configuration file
88/// paths from.
89static cl::opt<std::string> ConfigPathsFile(
90 "instrumentor-read-config-paths-file",
91 cl::desc("Read the instrumentor configuration file "
92 "paths from the specified file (newline separated)"),
93 cl::init(""));
94
95/// Set the debug location, if not set, after changing the insertion point of
96/// the IR builder \p IRB.
97template <typename IRBuilderTy> void ensureDbgLoc(IRBuilderTy &IRB) {
98 if (IRB.getCurrentDebugLocation())
99 return;
100 auto *BB = IRB.GetInsertBlock();
101 if (auto *SP = BB->getParent()->getSubprogram())
102 IRB.SetCurrentDebugLocation(DILocation::get(BB->getContext(), 0, 0, SP));
103}
104
105/// Attempt to cast \p V to type \p Ty using only bit-preserving casts.
106/// This ensures that floating-point values are converted via bitcast (not
107/// fptosi/fptoui) to preserve their exact bit representation.
108template <typename IRBTy>
109Value *tryToCast(IRBTy &IRB, Value *V, Type *Ty, const DataLayout &DL,
110 bool AllowTruncate = false) {
111 if (!V)
112 return Constant::getAllOnesValue(Ty);
113 Type *VTy = V->getType();
114 if (VTy == Ty)
115 return V;
116 if (VTy->isAggregateType() || VTy->isVectorTy())
117 return V;
118 if (VTy->isPointerTy() && Ty->isPointerTy())
119 return IRB.CreatePointerBitCastOrAddrSpaceCast(V, Ty);
120 TypeSize RequestedSize = DL.getTypeSizeInBits(Ty);
121 TypeSize ValueSize = DL.getTypeSizeInBits(VTy);
122 bool ShouldTruncate = RequestedSize < ValueSize;
123 if (ShouldTruncate && !AllowTruncate)
124 return V;
125 if (ShouldTruncate && AllowTruncate) {
126 // First convert to integer of the same size if needed.
127 Value *IntV = V;
128 if (VTy->isFloatingPointTy())
129 IntV = IRB.CreateBitCast(V, IRB.getIntNTy(ValueSize));
130 return tryToCast(IRB,
131 IRB.CreateIntCast(IntV, IRB.getIntNTy(RequestedSize),
132 /*IsSigned=*/false),
133 Ty, DL, AllowTruncate);
134 }
135 if (VTy->isIntegerTy() && Ty->isIntegerTy())
136 return IRB.CreateIntCast(V, Ty, /*IsSigned=*/false);
137 // Use bit-preserving casts for floating-point values: convert float to int
138 // of the same size via bitcast, then extend/truncate the integer if needed.
139 if (VTy->isFloatingPointTy() && Ty->isIntOrPtrTy()) {
140 return tryToCast(IRB, IRB.CreateBitCast(V, IRB.getIntNTy(ValueSize)), Ty,
141 DL, AllowTruncate);
142 }
143 // When converting int to float, never use sitofp/uitofp as they perform value
144 // conversion, not bit-preserving cast.
145 if (VTy->isIntegerTy() && Ty->isFloatingPointTy()) {
146 if (ValueSize == RequestedSize)
147 return IRB.CreateBitCast(V, Ty);
148 return tryToCast(
149 IRB,
150 IRB.CreateIntCast(V, IRB.getIntNTy(RequestedSize), /*IsSigned=*/false),
151 Ty, DL, AllowTruncate);
152 }
153 return IRB.CreateBitOrPointerCast(V, Ty);
154}
155
156/// Get a constant integer/boolean of type \p IT and value \p Val.
157template <typename Ty>
158Constant *getCI(Type *IT, Ty Val, bool IsSigned = false) {
159 return ConstantInt::get(IT, Val, IsSigned);
160}
161
162Constant *getSubTypeID(Type &OpTy, Type &ReqTy) {
163 switch (OpTy.getTypeID()) {
164 case Type::TypeID::ArrayTyID:
165 case Type::TypeID::FixedVectorTyID:
166 case Type::TypeID::ScalableVectorTyID:
167 return getCI(&ReqTy, OpTy.getContainedType(0)->getTypeID());
168 default:
169 break;
170 }
171
172 return getCI(&ReqTy, -1, /*IsSigned=*/true);
173}
174
175/// The core of the instrumentor pass, which instruments the module as the
176/// instrumentation configuration mandates.
177class InstrumentorImpl final {
178public:
179 /// Construct an instrumentor implementation using the configuration \p IConf.
180 InstrumentorImpl(InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB,
181 Module &M)
182 : IConf(IConf), M(M), IIRB(IIRB) {}
183
184 /// Instrument the module, public entry point.
185 bool instrument();
186
187 // Reset the state to allow reuse of the instrumentor with a different
188 // configuration.
189 void clear() {
190 InstChoicesPRE.clear();
191 InstChoicesPOST.clear();
192 ParsedFunctionRegex = Regex();
193 }
194
195private:
196 void linkRuntime();
197
198 /// Indicate if the module should be instrumented based on the target.
199 bool shouldInstrumentTarget();
200
201 /// Indicate if the function \p Fn should be instrumented.
202 bool shouldInstrumentFunction(Function &Fn);
203 bool shouldInstrumentGlobalVariable(GlobalVariable &GV);
204
205 /// Instrument instruction \p I if needed, and use the argument caches in \p
206 /// ICaches.
207 bool instrumentInstruction(Instruction &I, InstrumentationCaches &ICaches);
208
209 /// Instrument function \p Fn.
210 bool instrumentFunction(Function &Fn);
211 bool instrumentModule();
212
213 /// The instrumentation opportunities for instructions indexed by
214 /// their opcode.
216 InstChoicesPOST;
217
218 /// The instrumentor configuration.
220
221 /// The function regex filter, if any.
222 Regex ParsedFunctionRegex;
223
224 /// The underlying module.
225 Module &M;
226
227protected:
228 /// A special IR builder that keeps track of the inserted instructions.
230};
231
232} // end anonymous namespace
233
235 if (!Str.empty()) {
236 Regex RX(Str);
237 std::string ErrMsg;
238 if (!RX.isValid(ErrMsg)) {
240 Twine("failed to parse ") + Name + " regex: " + ErrMsg, DS_Error));
241 return Regex();
242 }
243 return RX;
244 }
245 return Regex();
246}
247
248void InstrumentorImpl::linkRuntime() {
249 const auto RuntimeBitcode = IConf.RuntimeBitcode->getString();
250 if (RuntimeBitcode.empty())
251 return;
252
253 SMDiagnostic Err;
254 auto RTM = parseIRFile(RuntimeBitcode, Err, M.getContext());
255 if (!RTM) {
256 IIRB.Ctx.diagnose(DiagnosticInfoInstrumentation(
257 Twine("Failed to parse runtime bitcode file '") + RuntimeBitcode +
258 Twine("':\n") + M.getName(),
259 DS_Error));
260 return;
261 }
262
263 auto InternalizeCallback = [&](Module &M, const StringSet<> &GVS) {
264 internalizeModule(M, [&GVS](const GlobalValue &GV) {
265 return !GV.hasName() || !GVS.count(GV.getName());
266 });
267 };
268
269 if (Linker::linkModules(M, std::move(RTM), 0, InternalizeCallback)) {
270 IIRB.Ctx.diagnose(DiagnosticInfoInstrumentation(
271 "Failed to link in runtime bitcode", DS_Error));
272 return;
273 }
274
275 if (!IConf.InlineRuntimeEagerly->getBool())
276 return;
277
278 for (auto [I, _] : IIRB.NewInsts) {
279 auto *CI = dyn_cast<CallInst>(I);
280 if (!CI || isa<IntrinsicInst>(CI))
281 continue;
282
283 InlineFunctionInfo IFI;
284 auto InlineResult = InlineFunction(*CI, IFI);
285 if (!InlineResult.isSuccess()) {
286 std::string WarnMsg;
287 raw_string_ostream SS(WarnMsg);
288 SS << "Inlining of runtime call failed: "
289 << CI->getCalledFunction()->getName() << "\n";
290 SS << "Reason: " << InlineResult.getFailureReason() << "\n";
291 SS << "Signatures: " << *CI->getFunctionType() << " vs "
292 << *CI->getCalledFunction()->getFunctionType() << "\n";
293 IIRB.Ctx.diagnose(DiagnosticInfoInstrumentation(WarnMsg, DS_Warning));
294 }
295 }
296
297 // Promote any eligible instrumentor-associated allocas to registers.
298 for (auto It : IIRB.AllocaMap) {
299 auto *Fn = It.first.first;
300 DominatorTree DT(*Fn);
301 auto &Allocas = *It.second;
302 erase_if(Allocas,
303 [](const AllocaInst *AI) { return !isAllocaPromotable(AI); });
304 PromoteMemToReg(Allocas, DT);
305 delete It.second;
306 }
307 IIRB.AllocaMap.clear();
308}
309
310bool InstrumentorImpl::shouldInstrumentTarget() {
311 const Triple &T = M.getTargetTriple();
312 const bool IsGPU = T.isAMDGPU() || T.isNVPTX();
313
314 bool RegexMatches = true;
315 Regex RX = createRegex(IConf.TargetRegex->getString(), "target", IIRB.Ctx);
316 if (RX.isValid())
317 RegexMatches = RX.match(T.str());
318
319 // Only instrument the module if the target has to be instrumented.
320 return ((IsGPU && IConf.GPUEnabled->getBool()) ||
321 (!IsGPU && IConf.HostEnabled->getBool())) &&
322 RegexMatches;
323}
324
325bool InstrumentorImpl::shouldInstrumentFunction(Function &Fn) {
326 if (Fn.isDeclaration())
327 return false;
328 bool RegexMatches = true;
329 if (ParsedFunctionRegex.isValid())
330 RegexMatches = ParsedFunctionRegex.match(Fn.getName());
331 return (RegexMatches && !Fn.getName().starts_with(IConf.getRTName())) ||
332 Fn.hasFnAttribute("instrument");
333}
334
335bool InstrumentorImpl::shouldInstrumentGlobalVariable(GlobalVariable &GV) {
336 return !GV.getName().starts_with("llvm.") &&
337 !GV.getName().starts_with(IConf.getRTName());
338}
339
340bool InstrumentorImpl::instrumentInstruction(Instruction &I,
341 InstrumentationCaches &ICaches) {
342 bool Changed = false;
343
344 // Skip instrumentation instructions.
345 if (IIRB.NewInsts.contains(&I))
346 return Changed;
347
348 // Count epochs eagerly.
349 ++IIRB.Epoch;
350
351 Value *IPtr = &I;
352 if (auto *IO = InstChoicesPRE.lookup(I.getOpcode())) {
353 IIRB.IRB.SetInsertPoint(&I);
354 ensureDbgLoc(IIRB.IRB);
355 IO->instrument(IPtr, Changed, IConf, IIRB, ICaches);
356 }
357
358 if (auto *IO = InstChoicesPOST.lookup(I.getOpcode())) {
359 IIRB.IRB.SetInsertPoint(I.getNextNode());
360 ensureDbgLoc(IIRB.IRB);
361 IO->instrument(IPtr, Changed, IConf, IIRB, ICaches);
362 }
363 IIRB.returnAllocas();
364
365 return Changed;
366}
367
368bool InstrumentorImpl::instrumentFunction(Function &Fn) {
369 bool Changed = false;
370 if (!shouldInstrumentFunction(Fn))
371 return Changed;
372
373 InstrumentationCaches ICaches;
374 SmallVector<Instruction *> FinalTIs;
375 ReversePostOrderTraversal<Function *> RPOT(&Fn);
376 for (auto &It : RPOT) {
377 for (auto &I : *It)
378 Changed |= instrumentInstruction(I, ICaches);
379
380 auto *TI = It->getTerminator();
381 if (!TI->getNumSuccessors())
382 FinalTIs.push_back(TI);
383 }
384
385 Value *FPtr = &Fn;
386 for (auto &[Name, IO] :
388 if (!IO->Enabled)
389 continue;
390 // Count epochs eagerly.
391 ++IIRB.Epoch;
392
393 IIRB.IRB.SetInsertPoint(
394 cast<Function>(FPtr)->getEntryBlock().getFirstNonPHIOrDbgOrAlloca());
395 ensureDbgLoc(IIRB.IRB);
396 IO->instrument(FPtr, Changed, IConf, IIRB, ICaches);
397 IIRB.returnAllocas();
398 }
399
400 for (auto &[Name, IO] :
402 if (!IO->Enabled)
403 continue;
404 // Count epochs eagerly.
405 ++IIRB.Epoch;
406
407 for (Instruction *FinalTI : FinalTIs) {
408 IIRB.IRB.SetInsertPoint(FinalTI);
409 ensureDbgLoc(IIRB.IRB);
410 IO->instrument(FPtr, Changed, IConf, IIRB, ICaches);
411 IIRB.returnAllocas();
412 }
413 }
414 return Changed;
415}
416
417bool InstrumentorImpl::instrumentModule() {
419 Globals.reserve(M.global_size());
420 for (GlobalVariable &GV : M.globals()) {
421 // llvm.metadata contains globals such as llvm.used.
422 if (GV.getSection() == "llvm.metadata" ||
423 GV.getName() == "llvm.global_dtors" ||
424 GV.getName() == "llvm.global_ctors")
425 continue;
426 Globals.push_back(&GV);
427 }
428
429 auto CreateYtor = [&](bool Ctor) {
430 Function *YtorFn = Function::Create(
431 FunctionType::get(IIRB.VoidTy, false), GlobalValue::PrivateLinkage,
432 IConf.getRTName(Ctor ? "ctor" : "dtor", ""), M);
433
434 auto *EntryBB = BasicBlock::Create(IIRB.Ctx, "entry", YtorFn);
435 IIRB.IRB.SetInsertPoint(EntryBB->begin());
436 ensureDbgLoc(IIRB.IRB);
437 IIRB.IRB.CreateRetVoid();
438
439 if (Ctor)
440 appendToGlobalCtors(M, YtorFn, 1000);
441 else
442 appendToGlobalDtors(M, YtorFn, 1000);
443 return YtorFn;
444 };
445
446 InstrumentationCaches ICaches;
447
448 Function *CtorFn = nullptr, *DtorFn = nullptr;
449 bool Changed = false;
452 bool IsPRE = InstrumentationLocation::isPRE(Loc);
453 Function *&YtorFn = IsPRE ? CtorFn : DtorFn;
454 for (auto &ChoiceIt : IConf.IChoices[Loc]) {
455 auto *IO = ChoiceIt.second;
456 if (!IO->Enabled)
457 continue;
458 if (!YtorFn) {
459 YtorFn = CreateYtor(IsPRE);
460 Changed = true;
461 }
462 IIRB.IRB.SetInsertPointPastAllocas(YtorFn);
463 ensureDbgLoc(IIRB.IRB);
464 Value *YtorPtr = YtorFn;
465
466 // Count epochs eagerly.
467 ++IIRB.Epoch;
468
469 IO->instrument(YtorPtr, Changed, IConf, IIRB, ICaches);
470 IIRB.returnAllocas();
471 }
472 }
473
476 bool IsPRE = InstrumentationLocation::isPRE(Loc);
477 Function *&YtorFn = IsPRE ? CtorFn : DtorFn;
478 for (auto &ChoiceIt : IConf.IChoices[Loc]) {
479 auto *IO = ChoiceIt.second;
480 if (!IO->Enabled)
481 continue;
482 if (!YtorFn) {
483 YtorFn = CreateYtor(IsPRE);
484 Changed = true;
485 }
486 for (GlobalVariable *GV : Globals) {
487 if (!shouldInstrumentGlobalVariable(*GV))
488 continue;
489 if (IsPRE)
490 IIRB.IRB.SetInsertPoint(YtorFn->getEntryBlock().getTerminator());
491 else
492 IIRB.IRB.SetInsertPointPastAllocas(YtorFn);
493 ensureDbgLoc(IIRB.IRB);
494 Value *GVPtr = GV;
495
496 // Count epochs eagerly.
497 ++IIRB.Epoch;
498
499 IO->instrument(GVPtr, Changed, IConf, IIRB, ICaches);
500 IIRB.returnAllocas();
501 }
502 }
503 }
504
505 return Changed;
506}
507
508bool InstrumentorImpl::instrument() {
509 bool Changed = false;
510 if (!shouldInstrumentTarget())
511 return Changed;
512
513 StringRef FunctionRegexStr = IConf.FunctionRegex->getString();
514 ParsedFunctionRegex = createRegex(FunctionRegexStr, "function", IIRB.Ctx);
515
516 // Helper to register an IO for all its opcodes.
517 auto RegisterForAllOpcodes = [](auto &InstChoices,
518 InstrumentationOpportunity *IO) {
519 ArrayRef<unsigned> Opcodes = IO->getAllOpcodes();
520 // Register for all opcodes.
521 for (unsigned Opcode : Opcodes)
522 InstChoices[Opcode] = IO;
523 };
524
525 for (auto &[Name, IO] :
527 if (IO->Enabled)
528 RegisterForAllOpcodes(InstChoicesPRE, IO);
529 for (auto &[Name, IO] :
531 if (IO->Enabled)
532 RegisterForAllOpcodes(InstChoicesPOST, IO);
533 Changed |= instrumentModule();
534
535 for (Function &Fn : M)
536 Changed |= instrumentFunction(Fn);
537
538 linkRuntime();
539
540 return Changed;
541}
542
544 InstrumentationConfig *IC,
545 InstrumentorIRBuilderTy *IIRB)
546 : FS(FS), UserIConf(IC), UserIIRB(IIRB) {
547 if (!FS)
548 this->FS = vfs::getRealFileSystem();
549}
550
551PreservedAnalyses InstrumentorPass::run(Module &M, InstrumentationConfig &IConf,
553 bool ReadConfig) {
554 bool Changed = false;
555 InstrumentorImpl Impl(IConf, IIRB, M);
556
557 // If this is a configuration driven run, iterate over all configurations
558 // provided by the user, if not, use the config as is and run the instrumentor
559 // once.
560 if (ReadConfig)
561 readConfigPathsFile(ConfigPathsFile, ConfigFiles, IIRB.Ctx, *FS);
562
563 bool MultipleConfigs = ConfigFiles.size() > 1;
564 unsigned Idx = 0;
565 do {
566 std::string ConfigFile =
567 ReadConfig && !ConfigFiles.empty() ? ConfigFiles[Idx] : "";
568
569 // Initialize the config to the base state but keep the caches around.
570 Impl.clear();
571 IConf.init(IIRB);
572
573 if (!readConfigFromJSON(IConf, ConfigFile, IIRB.Ctx, *FS))
574 continue;
575
576 writeConfigToJSON(IConf,
577 MultipleConfigs
578 ? OutputConfigFile + "." + std::to_string(Idx)
579 : OutputConfigFile,
580 IIRB.Ctx);
581
582 printRuntimeStub(IConf, IConf.RuntimeStubsFile->getString(), IIRB.Ctx);
583
584 Changed |= Impl.instrument();
585 } while (++Idx < ConfigFiles.size());
586
587 if (!Changed)
588 return PreservedAnalyses::all();
590}
591
593 // Only create them if the user did not provide them.
594 std::unique_ptr<InstrumentationConfig> IConfInt(
595 !UserIConf ? new InstrumentationConfig() : nullptr);
596 std::unique_ptr<InstrumentorIRBuilderTy> IIRBInt(
597 !UserIIRB ? new InstrumentorIRBuilderTy(M) : nullptr);
598
599 auto *IConf = IConfInt ? IConfInt.get() : UserIConf;
600 auto *IIRB = IIRBInt ? IIRBInt.get() : UserIIRB;
601
602 auto PA = run(M, *IConf, *IIRB, !UserIConf);
603
604 assert(!verifyModule(M, &errs()));
605 return PA;
606}
607
608std::unique_ptr<BaseConfigurationOption>
611 bool DefaultValue) {
612 auto BCO =
613 std::make_unique<BaseConfigurationOption>(Name, Description, BOOLEAN);
614 BCO->setBool(DefaultValue);
615 IConf.addBaseChoice(BCO.get());
616 return BCO;
617}
618
619std::unique_ptr<BaseConfigurationOption>
623 StringRef DefaultValue) {
624 auto BCO =
625 std::make_unique<BaseConfigurationOption>(Name, Description, STRING);
626 BCO->setString(DefaultValue);
627 IConf.addBaseChoice(BCO.get());
628 return BCO;
629}
630
632 /// List of all instrumentation opportunities.
633 BasePointerIO::populate(*this, IIRB);
634 ModuleIO::populate(*this, IIRB);
635 GlobalVarIO::populate(*this, IIRB);
636 FunctionIO::populate(*this, IIRB);
637 AllocaIO::populate(*this, IIRB);
638 UnreachableIO::populate(*this, IIRB);
639 LoadIO::populate(*this, IIRB);
640 StoreIO::populate(*this, IIRB);
641 CastIO::populate(*this, IIRB);
642 NumericIO::populate(*this, IIRB);
643 CompareIO::populate(*this, IIRB);
644}
645
647 LLVMContext &Ctx) {
648 auto *&ICPtr = IChoices[IO.getLocationKind()][IO.getName()];
649 if (ICPtr) {
651 Twine("registered two instrumentation opportunities for the same "
652 "location (") +
653 ICPtr->getName() + Twine(" vs ") + IO.getName() + Twine(")"),
654 DS_Warning));
655 }
656 ICPtr = &IO;
657}
658
659Value *
662 Function *Fn = IIRB.IRB.GetInsertBlock()->getParent();
663
664 Value *Obj;
665 {
666 Value *&UnderlyingObj = UnderlyingObjsMap[&V];
667 if (!UnderlyingObj)
668 UnderlyingObj = const_cast<Value *>(getUnderlyingObjectAggressive(&V));
669 Obj = UnderlyingObj;
670 }
671
672 Value *&BPI = BasePointerInfoMap[{Obj, Fn}];
673 if (BPI)
674 return BPI;
675
676 auto *BPIO =
678 if (!BPIO || !BPIO->Enabled) {
680 "Base pointer info disabled but required, passing nullptr.",
681 DS_Warning));
682 return BPI = Constant::getNullValue(BPIO->getRetTy(IIRB.Ctx));
683 }
684
686 if (auto *BasePtrI = dyn_cast<Instruction>(Obj)) {
687 std::optional<BasicBlock::iterator> IP =
688 BasePtrI->getInsertionPointAfterDef();
689 if (IP) {
690 IIRB.IRB.SetInsertPoint(*IP);
691 } else {
693 "Base pointer info could not be placed, passing nullptr.",
694 DS_Warning));
695 return BPI = Constant::getNullValue(BPIO->getRetTy(IIRB.Ctx));
696 }
697 } else if (isa<Constant>(Obj) || isa<Argument>(Obj)) {
698 IIRB.IRB.SetInsertPointPastAllocas(IIRB.IRB.GetInsertBlock()->getParent());
699 } else {
700 LLVM_DEBUG(Obj->dump());
701 llvm_unreachable("Unexpected base pointer!");
702 }
703 ensureDbgLoc(IIRB.IRB);
704
705 // Use fresh caches for safety, as this function may be called from
706 // another instrumentation opportunity.
707 bool Changed;
708 InstrumentationCaches ICaches;
709 BPI = BPIO->instrument(Obj, Changed, *this, IIRB, ICaches);
710 IIRB.returnAllocas();
711 if (!BPI)
712 BPI = Constant::getNullValue(BPIO->getRetTy(IIRB.Ctx));
713 return BPI;
714}
715
719 return getCI(&Ty, getIdFromEpoch(IIRB.Epoch));
720}
721
725 return getCI(&Ty, -getIdFromEpoch(IIRB.Epoch), /*IsSigned=*/true);
726}
727
730 if (V.getType()->isVoidTy())
731 return Ty.isVoidTy() ? &V : Constant::getNullValue(&Ty);
732 return tryToCast(IIRB.IRB, &V, &Ty, IIRB.IRB.getDataLayout());
733}
734
738 if (V.getType()->isVoidTy())
739 return &V;
740
741 auto *NewVCasted = &NewV;
742 if (auto *I = dyn_cast<Instruction>(&NewV)) {
744 IIRB.IRB.SetInsertPoint(I->getNextNode());
745 ensureDbgLoc(IIRB.IRB);
746 NewVCasted = tryToCast(IIRB.IRB, &NewV, V.getType(), IIRB.DL,
747 /*AllowTruncate=*/true);
748 }
749 V.replaceUsesWithIf(NewVCasted, [&](Use &U) {
750 if (IIRB.NewInsts.lookup(cast<Instruction>(U.getUser())) == IIRB.Epoch)
751 return false;
752 return !isa<LifetimeIntrinsic>(U.getUser()) && !U.getUser()->isDroppable();
753 });
754
755 return &V;
756}
757
759 Type *RetTy)
760 : IO(IO), RetTy(RetTy) {
761 for (auto &It : IO.IRTArgs) {
762 if (!It.Enabled)
763 continue;
764 NumReplaceableArgs += bool(It.Flags & IRTArg::REPLACABLE);
765 MightRequireIndirection |= It.Flags & IRTArg::POTENTIALLY_INDIRECT;
766 }
769}
770
773 const DataLayout &DL, bool ForceIndirection) {
774 assert(((ForceIndirection && MightRequireIndirection) ||
775 (!ForceIndirection && !RequiresIndirection)) &&
776 "Wrong indirection setting!");
777
778 SmallVector<Type *> ParamTypes;
779 for (auto &It : IO.IRTArgs) {
780 if (!It.Enabled)
781 continue;
782 if (!ForceIndirection || !isPotentiallyIndirect(It)) {
783 ParamTypes.push_back(It.Ty);
784 if (!RetTy && NumReplaceableArgs == 1 && (It.Flags & IRTArg::REPLACABLE))
785 RetTy = It.Ty;
786 continue;
787 }
788
789 // The indirection pointer and the size of the value.
790 ParamTypes.push_back(IIRB.PtrTy);
791 if (!(It.Flags & IRTArg::INDIRECT_HAS_SIZE))
792 ParamTypes.push_back(IIRB.Int32Ty);
793 }
794 if (!RetTy)
795 RetTy = IIRB.VoidTy;
796
797 return FunctionType::get(RetTy, ParamTypes, /*isVarArg=*/false);
798}
799
803 const DataLayout &DL,
804 InstrumentationCaches &ICaches) {
805 SmallVector<Value *> CallParams;
806
808 auto IP = IIRB.IRB.GetInsertPoint();
809
810 bool ForceIndirection = RequiresIndirection;
811 for (auto &It : IO.IRTArgs) {
812 if (!It.Enabled)
813 continue;
814 auto *&Param = ICaches.DirectArgCache[{IIRB.Epoch, IO.getName(), It.Name}];
815 if (!Param || It.NoCache)
816 // Avoid passing the caches to the getter.
817 Param = It.GetterCB(*V, *It.Ty, IConf, IIRB);
818 assert(Param);
819
820 if (Param->getType()->isVoidTy()) {
821 Param = Constant::getNullValue(It.Ty);
822 } else if (Param->getType()->isAggregateType() ||
823 Param->getType()->isVectorTy() ||
824 DL.getTypeSizeInBits(Param->getType()) >
825 DL.getTypeSizeInBits(It.Ty)) {
826 if (!isPotentiallyIndirect(It)) {
828 Twine("indirection needed for ") + It.Name + Twine(" in ") +
829 IO.getName() +
830 Twine(", but not indicated. Instrumentation is skipped"),
831 DS_Warning));
832 return nullptr;
833 }
834 ForceIndirection = true;
835 } else {
836 Param = tryToCast(IIRB.IRB, Param, It.Ty, DL);
837 }
838 CallParams.push_back(Param);
839 }
840
841 if (ForceIndirection) {
842 Function *Fn = IIRB.IRB.GetInsertBlock()->getParent();
843
844 unsigned Offset = 0;
845 for (auto &It : IO.IRTArgs) {
846 if (!It.Enabled)
847 continue;
848
849 if (!isPotentiallyIndirect(It)) {
850 ++Offset;
851 continue;
852 }
853 auto *&CallParam = CallParams[Offset++];
854 if (!(It.Flags & IRTArg::INDIRECT_HAS_SIZE)) {
855 CallParams.insert(&CallParam + 1, IIRB.IRB.getInt32(DL.getTypeStoreSize(
856 CallParam->getType())));
857 Offset += 1;
858 }
859
860 auto *&CachedParam =
861 ICaches.IndirectArgCache[{IIRB.Epoch, IO.getName(), It.Name}];
862 if (CachedParam) {
863 CallParam = CachedParam;
864 continue;
865 }
866
867 auto *AI = IIRB.getAlloca(Fn, CallParam->getType());
868 IIRB.IRB.CreateStore(CallParam, AI);
869 CallParam = CachedParam = tryToCast(IIRB.IRB, AI, IIRB.PtrTy, DL);
870 }
871 }
872
873 if (!ForceIndirection)
874 IIRB.IRB.SetInsertPoint(IP);
875 ensureDbgLoc(IIRB.IRB);
876
877 auto *FnTy = createLLVMSignature(IConf, IIRB, DL, ForceIndirection);
878 auto CompleteName =
879 IConf.getRTName(IO.IP.isPRE() ? "pre_" : "post_", IO.getName(),
880 ForceIndirection ? "_ind" : "");
881 auto FC = IIRB.IRB.getModule()->getOrInsertFunction(CompleteName, FnTy);
882 auto *CI = IIRB.IRB.CreateCall(FC, CallParams);
883 CI->addFnAttr(Attribute::get(IIRB.Ctx, Attribute::WillReturn));
884
885 for (unsigned I = 0, E = IO.IRTArgs.size(); I < E; ++I) {
886 if (!IO.IRTArgs[I].Enabled)
887 continue;
888 if (!isReplacable(IO.IRTArgs[I]))
889 continue;
890 bool IsCustomReplaceable = IO.IRTArgs[I].Flags & IRTArg::REPLACABLE_CUSTOM;
891 Value *NewValue = FnTy->isVoidTy() || IsCustomReplaceable
892 ? ICaches.DirectArgCache[{IIRB.Epoch, IO.getName(),
893 IO.IRTArgs[I].Name}]
894 : CI;
895 assert(NewValue);
896 if (ForceIndirection && !IsCustomReplaceable &&
897 isPotentiallyIndirect(IO.IRTArgs[I])) {
898 auto *Q =
899 ICaches
900 .IndirectArgCache[{IIRB.Epoch, IO.getName(), IO.IRTArgs[I].Name}];
901 NewValue = IIRB.IRB.CreateLoad(V->getType(), Q);
902 }
903 V = IO.IRTArgs[I].SetterCB(*V, *NewValue, IConf, IIRB);
904 }
905 return CI;
906}
907
908template <typename Ty> constexpr static Value *getValue(Ty &ValueOrUse) {
909 if constexpr (std::is_same<Ty, Use>::value)
910 return ValueOrUse.get();
911 else
912 return static_cast<Value *>(&ValueOrUse);
913}
914
915template <typename Range>
918 auto *Fn = IIRB.IRB.GetInsertBlock()->getParent();
919 auto *I32Ty = IIRB.IRB.getInt32Ty();
920 SmallVector<Constant *> ConstantValues;
923 for (auto &RE : R) {
924 Value *V = getValue(RE);
925 if (!V->getType()->isSized())
926 continue;
927 auto VSize = IIRB.DL.getTypeAllocSize(V->getType());
928 ConstantValues.push_back(getCI(I32Ty, VSize));
929 Types.push_back(I32Ty);
930 ConstantValues.push_back(getCI(I32Ty, V->getType()->getTypeID()));
931 Types.push_back(I32Ty);
932 if (uint32_t MisAlign = VSize % 8) {
933 Types.push_back(ArrayType::get(IIRB.Int8Ty, 8 - MisAlign));
934 ConstantValues.push_back(ConstantArray::getNullValue(Types.back()));
935 }
936 Types.push_back(V->getType());
937 if (auto *C = dyn_cast<Constant>(V)) {
938 ConstantValues.push_back(C);
939 continue;
940 }
941 Values.push_back({V, ConstantValues.size()});
942 ConstantValues.push_back(Constant::getNullValue(V->getType()));
943 }
944 if (Types.empty())
945 return ConstantPointerNull::get(IIRB.PtrTy);
946
947 StructType *STy = StructType::get(Fn->getContext(), Types, /*isPacked=*/true);
948 Constant *Initializer = ConstantStruct::get(STy, ConstantValues);
949
950 GlobalVariable *&GV = IConf.ConstantGlobalsCache[Initializer];
951 if (!GV)
952 GV = new GlobalVariable(*Fn->getParent(), STy, false,
953 GlobalValue::InternalLinkage, Initializer,
954 IConf.getRTName("", "value_pack"));
955
956 auto *AI = IIRB.getAlloca(Fn, STy);
957 IIRB.IRB.CreateMemCpy(AI, AI->getAlign(), GV, GV->getAlign(),
958 IIRB.DL.getTypeAllocSize(STy));
959 for (auto [Param, Idx] : Values) {
960 auto *Ptr = IIRB.IRB.CreateStructGEP(STy, AI, Idx);
961 IIRB.IRB.CreateStore(Param, Ptr);
962 }
963 return AI;
964}
965
966template <typename Range>
967static void readValuePack(const Range &R, Value &Pack,
969 function_ref<void(int, Value *)> SetterCB) {
970 auto *Fn = IIRB.IRB.GetInsertBlock()->getParent();
971 auto &DL = Fn->getDataLayout();
972 SmallVector<Value *> ParameterValues;
973 unsigned Offset = 0;
974 for (const auto &[Idx, RE] : enumerate(R)) {
975 Value *V = getValue(RE);
976 if (!V->getType()->isSized())
977 continue;
978 Offset += 8;
979 auto VSize = DL.getTypeAllocSize(V->getType());
980 auto Padding = alignTo(VSize, 8) - VSize;
981 Offset += Padding;
982 auto *Ptr = IIRB.IRB.CreateConstInBoundsGEP1_32(IIRB.Int8Ty, &Pack, Offset);
983 auto *NewV = IIRB.IRB.CreateLoad(V->getType(), Ptr);
984 SetterCB(Idx, NewV);
985 Offset += VSize;
986 }
987}
988
992 auto &I = cast<Instruction>(V);
993 return getCI(&Ty, I.getOpcode());
994}
995
999 auto &I = cast<Instruction>(V);
1000 auto &DL = I.getDataLayout();
1001 return getCI(&Ty, DL.getTypeStoreSize(V.getType()));
1002}
1003
1005 InstrumentationConfig &IConf,
1007 auto &I = cast<Instruction>(V);
1008 return I.getOperand(0);
1009}
1010
1012 InstrumentationConfig &IConf,
1014 auto &I = cast<Instruction>(V);
1015 if (I.getNumOperands() > 1)
1016 return I.getOperand(1);
1017 return PoisonValue::get(&Ty);
1018}
1019
1021 InstrumentationConfig &IConf,
1023 return getCI(&Ty, V.getType()->getTypeID());
1024}
1025
1027 InstrumentationConfig &IConf,
1029 return getSubTypeID(*V.getType(), Ty);
1030}
1031
1032/// FunctionIO
1033/// {
1035 InstrumentorIRBuilderTy &IIRB, ConfigTy *UserConfig) {
1036 using namespace std::placeholders;
1037 if (UserConfig)
1038 Config = *UserConfig;
1039
1041 if (Config.has(PassAddress))
1042 IRTArgs.push_back(IRTArg(IIRB.PtrTy, "address", "The function address.",
1044 if (Config.has(PassName))
1045 IRTArgs.push_back(IRTArg(IIRB.PtrTy, "name", "The function name.",
1047 if (Config.has(PassNumArguments))
1048 IRTArgs.push_back(
1049 IRTArg(IIRB.Int32Ty, "num_arguments",
1050 "Number of function arguments (without varargs).", IRTArg::NONE,
1051 std::bind(&FunctionIO::getNumArguments, this, _1, _2, _3, _4)));
1052 if (Config.has(PassArguments))
1053 IRTArgs.push_back(IRTArg(
1054 IIRB.PtrTy, "arguments", "Description of the arguments.",
1056 : IRTArg::NONE) |
1058 std::bind(&FunctionIO::getArguments, this, _1, _2, _3, _4),
1059 std::bind(&FunctionIO::setArguments, this, _1, _2, _3, _4)));
1060 if (Config.has(PassIsMain))
1061 IRTArgs.push_back(IRTArg(IIRB.Int8Ty, "is_main",
1062 "Flag to indicate it is the main function.",
1064 addCommonArgs(IConf, IIRB.Ctx, Config.has(PassId));
1065 IConf.addChoice(*this, IIRB.Ctx);
1066}
1067
1069 InstrumentationConfig &IConf,
1071 auto &Fn = cast<Function>(V);
1072 if (Fn.isIntrinsic())
1073 return Constant::getNullValue(&Ty);
1074 return &V;
1075}
1077 InstrumentationConfig &IConf,
1079 auto &Fn = cast<Function>(V);
1080 return IConf.getGlobalString(IConf.DemangleFunctionNames->getBool()
1081 ? demangle(Fn.getName())
1082 : Fn.getName(),
1083 IIRB);
1084}
1086 InstrumentationConfig &IConf,
1088 auto &Fn = cast<Function>(V);
1089 if (!Config.ArgFilter)
1090 return getCI(&Ty, Fn.arg_size());
1091 auto FRange = make_filter_range(Fn.args(), Config.ArgFilter);
1092 return getCI(&Ty, std::distance(FRange.begin(), FRange.end()));
1093}
1095 InstrumentationConfig &IConf,
1097 auto &Fn = cast<Function>(V);
1098 if (!Config.ArgFilter)
1099 return createValuePack(Fn.args(), IConf, IIRB);
1100 return createValuePack(make_filter_range(Fn.args(), Config.ArgFilter), IConf,
1101 IIRB);
1102}
1104 InstrumentationConfig &IConf,
1106 auto &Fn = cast<Function>(V);
1107 auto *AIt = Fn.arg_begin();
1108 auto CB = [&](int Idx, Value *ReplV) {
1109 while (Config.ArgFilter && !Config.ArgFilter(*AIt))
1110 ++AIt;
1111 Fn.getArg(Idx)->replaceUsesWithIf(ReplV, [&](Use &U) {
1112 return IIRB.NewInsts.lookup(cast<Instruction>(U.getUser())) != IIRB.Epoch;
1113 });
1114 ++AIt;
1115 };
1116 if (!Config.ArgFilter)
1117 readValuePack(Fn.args(), NewV, IIRB, CB);
1118 else
1119 readValuePack(make_filter_range(Fn.args(), Config.ArgFilter), NewV, IIRB,
1120 CB);
1121 return &Fn;
1122}
1124 InstrumentationConfig &IConf,
1126 auto &Fn = cast<Function>(V);
1127 return getCI(&Ty, Fn.getName() == "main");
1128}
1129
1130/// UnreachableIO
1131///{
1133 InstrumentorIRBuilderTy &IIRB, ConfigTy *UserConfig) {
1134 if (UserConfig)
1135 Config = *UserConfig;
1136 addCommonArgs(IConf, IIRB.Ctx, Config.has(PassId));
1137 IConf.addChoice(*this, IIRB.Ctx);
1138}
1139///}
1140
1141/// AllocaIO
1142///{
1144 ConfigTy *UserConfig) {
1145 if (UserConfig)
1146 Config = *UserConfig;
1147
1149 if (!IsPRE && Config.has(PassAddress))
1150 IRTArgs.push_back(
1151 IRTArg(IIRB.PtrTy, "address", "The allocated memory address.",
1155 if (Config.has(PassSize))
1156 IRTArgs.push_back(IRTArg(
1157 IIRB.Int64Ty, "size", "The allocation size.",
1159 getSize, setSize));
1160 if (Config.has(PassAlignment))
1161 IRTArgs.push_back(IRTArg(IIRB.Int64Ty, "alignment",
1162 "The allocation alignment.", IRTArg::NONE,
1163 getAlignment));
1164
1165 addCommonArgs(IConf, IIRB.Ctx, Config.has(PassId));
1166 IConf.addChoice(*this, IIRB.Ctx);
1167}
1168
1171 auto &AI = cast<AllocaInst>(V);
1172 return IIRB.IRB.CreateAllocationSize(&Ty, &AI);
1173}
1174
1177 auto &AI = cast<AllocaInst>(V);
1178 const DataLayout &DL = AI.getDataLayout();
1179 auto *NewAI = IIRB.IRB.CreateAlloca(IIRB.IRB.getInt8Ty(),
1180 DL.getAllocaAddrSpace(), &NewV);
1181 NewAI->setAlignment(AI.getAlign());
1182 AI.replaceAllUsesWith(NewAI);
1183 IIRB.eraseLater(&AI);
1184 return NewAI;
1185}
1186
1189 return getCI(&Ty, cast<AllocaInst>(V).getAlign().value());
1190}
1191///}
1192
1194 ConfigTy *UserConfig) {
1195 if (UserConfig)
1196 Config = *UserConfig;
1197
1199 if (Config.has(PassPointer)) {
1200 IRTArgs.push_back(
1201 IRTArg(IIRB.PtrTy, "pointer", "The accessed pointer.",
1202 ((IsPRE && Config.has(ReplacePointer)) ? IRTArg::REPLACABLE
1203 : IRTArg::NONE),
1205 }
1206 if (Config.has(PassPointerAS)) {
1207 IRTArgs.push_back(IRTArg(IIRB.Int32Ty, "pointer_as",
1208 "The address space of the accessed pointer.",
1210 }
1211 if (Config.has(PassBasePointerInfo)) {
1212 IRTArgs.push_back(IRTArg(IIRB.PtrTy, "base_pointer_info",
1213 "The runtime provided base pointer info.",
1215 }
1216 if (Config.has(PassStoredValue)) {
1217 IRTArgs.push_back(
1218 IRTArg(getValueType(IIRB), "value", "The stored value.",
1221 : IRTArg::NONE),
1222 getValue));
1223 }
1224 if (Config.has(PassStoredValueSize)) {
1225 IRTArgs.push_back(IRTArg(IIRB.Int64Ty, "value_size",
1226 "The size of the stored value.", IRTArg::NONE,
1227 getValueSize));
1228 }
1229 if (Config.has(PassAlignment)) {
1230 IRTArgs.push_back(IRTArg(IIRB.Int64Ty, "alignment",
1231 "The known access alignment.", IRTArg::NONE,
1232 getAlignment));
1233 }
1234 if (Config.has(PassValueTypeId)) {
1235 IRTArgs.push_back(IRTArg(IIRB.Int32Ty, "value_type_id",
1236 "The type id of the stored value.", IRTArg::TYPEID,
1238 }
1239 if (Config.has(PassValueSubTypeId)) {
1240 IRTArgs.push_back(IRTArg(
1241 IIRB.Int32Ty, "value_sub_type_id",
1242 "The type id of the stored value (for arrays and vectors, or -1).",
1244 }
1245 if (Config.has(PassAtomicityOrdering)) {
1246 IRTArgs.push_back(IRTArg(IIRB.Int32Ty, "atomicity_ordering",
1247 "The atomicity ordering of the store.",
1249 }
1250 if (Config.has(PassSyncScopeId)) {
1251 IRTArgs.push_back(IRTArg(IIRB.Int8Ty, "sync_scope_id",
1252 "The sync scope id of the store.", IRTArg::NONE,
1254 }
1255 if (Config.has(PassIsVolatile)) {
1256 IRTArgs.push_back(IRTArg(IIRB.Int8Ty, "is_volatile",
1257 "Flag indicating a volatile store.", IRTArg::NONE,
1258 isVolatile));
1259 }
1260
1261 addCommonArgs(IConf, IIRB.Ctx, Config.has(PassId));
1262 IConf.addChoice(*this, IIRB.Ctx);
1263}
1264
1267 auto &SI = cast<StoreInst>(V);
1268 return SI.getPointerOperand();
1269}
1270
1273 auto &SI = cast<StoreInst>(V);
1274 SI.setOperand(SI.getPointerOperandIndex(), &NewV);
1275 return &SI;
1276}
1277
1280 auto &SI = cast<StoreInst>(V);
1281 return getCI(&Ty, SI.getPointerAddressSpace());
1282}
1283
1285 InstrumentationConfig &IConf,
1287 auto &SI = cast<StoreInst>(V);
1288 return IConf.getBasePointerInfo(*SI.getPointerOperand(), IIRB);
1289}
1290
1293 auto &SI = cast<StoreInst>(V);
1294 return SI.getValueOperand();
1295}
1296
1299 auto &SI = cast<StoreInst>(V);
1300 auto &DL = SI.getDataLayout();
1301 return getCI(&Ty, DL.getTypeStoreSize(SI.getValueOperand()->getType()));
1302}
1303
1306 auto &SI = cast<StoreInst>(V);
1307 return getCI(&Ty, SI.getAlign().value());
1308}
1309
1312 auto &SI = cast<StoreInst>(V);
1313 return getCI(&Ty, SI.getValueOperand()->getType()->getTypeID());
1314}
1315
1317 InstrumentationConfig &IConf,
1319 auto &SI = cast<StoreInst>(V);
1320 return getSubTypeID(*SI.getValueOperand()->getType(), Ty);
1321}
1322
1324 InstrumentationConfig &IConf,
1326 auto &SI = cast<StoreInst>(V);
1327 return getCI(&Ty, uint64_t(SI.getOrdering()));
1328}
1329
1332 auto &SI = cast<StoreInst>(V);
1333 return getCI(&Ty, uint64_t(SI.getSyncScopeID()));
1334}
1335
1338 auto &SI = cast<StoreInst>(V);
1339 return getCI(&Ty, SI.isVolatile());
1340}
1341
1343 ConfigTy *UserConfig) {
1345 if (UserConfig)
1346 Config = *UserConfig;
1347 if (Config.has(PassPointer)) {
1348 IRTArgs.push_back(
1349 IRTArg(IIRB.PtrTy, "pointer", "The accessed pointer.",
1350 ((IsPRE && Config.has(ReplacePointer)) ? IRTArg::REPLACABLE
1351 : IRTArg::NONE),
1353 }
1354 if (Config.has(PassPointerAS)) {
1355 IRTArgs.push_back(IRTArg(IIRB.Int32Ty, "pointer_as",
1356 "The address space of the accessed pointer.",
1358 }
1359 if (Config.has(PassBasePointerInfo)) {
1360 IRTArgs.push_back(IRTArg(IIRB.PtrTy, "base_pointer_info",
1361 "The runtime provided base pointer info.",
1363 }
1364 if (!IsPRE && Config.has(PassValue)) {
1365 IRTArgs.push_back(
1366 IRTArg(getValueType(IIRB), "value", "The loaded value.",
1367 Config.has(ReplaceValue)
1370 : IRTArg::NONE)
1371 : IRTArg::NONE,
1372 getValue, Config.has(ReplaceValue) ? replaceValue : nullptr));
1373 }
1374 if (Config.has(PassValueSize)) {
1375 IRTArgs.push_back(IRTArg(IIRB.Int64Ty, "value_size",
1376 "The size of the loaded value.", IRTArg::NONE,
1377 getValueSize));
1378 }
1379 if (Config.has(PassAlignment)) {
1380 IRTArgs.push_back(IRTArg(IIRB.Int64Ty, "alignment",
1381 "The known access alignment.", IRTArg::NONE,
1382 getAlignment));
1383 }
1384 if (Config.has(PassValueTypeId)) {
1385 IRTArgs.push_back(IRTArg(IIRB.Int32Ty, "value_type_id",
1386 "The type id of the loaded value.", IRTArg::TYPEID,
1388 }
1389 if (Config.has(PassValueSubTypeId)) {
1390 IRTArgs.push_back(IRTArg(
1391 IIRB.Int32Ty, "value_sub_type_id",
1392 "The sub type id of the loaded value (for arrays and vectors, or -1).",
1394 }
1395 if (Config.has(PassAtomicityOrdering)) {
1396 IRTArgs.push_back(IRTArg(IIRB.Int32Ty, "atomicity_ordering",
1397 "The atomicity ordering of the load.",
1399 }
1400 if (Config.has(PassSyncScopeId)) {
1401 IRTArgs.push_back(IRTArg(IIRB.Int8Ty, "sync_scope_id",
1402 "The sync scope id of the load.", IRTArg::NONE,
1404 }
1405 if (Config.has(PassIsVolatile)) {
1406 IRTArgs.push_back(IRTArg(IIRB.Int8Ty, "is_volatile",
1407 "Flag indicating a volatile load.", IRTArg::NONE,
1408 isVolatile));
1409 }
1410
1411 addCommonArgs(IConf, IIRB.Ctx, Config.has(PassId));
1412 IConf.addChoice(*this, IIRB.Ctx);
1413}
1414
1417 auto &LI = cast<LoadInst>(V);
1418 return LI.getPointerOperand();
1419}
1420
1423 auto &LI = cast<LoadInst>(V);
1424 LI.setOperand(LI.getPointerOperandIndex(), &NewV);
1425 return &LI;
1426}
1427
1430 auto &LI = cast<LoadInst>(V);
1431 return getCI(&Ty, LI.getPointerAddressSpace());
1432}
1433
1435 InstrumentationConfig &IConf,
1437 auto &LI = cast<LoadInst>(V);
1438 return IConf.getBasePointerInfo(*LI.getPointerOperand(), IIRB);
1439}
1440
1443 return &V;
1444}
1445
1448 auto &LI = cast<LoadInst>(V);
1449 auto &DL = LI.getDataLayout();
1450 return getCI(&Ty, DL.getTypeStoreSize(LI.getType()));
1451}
1452
1455 auto &LI = cast<LoadInst>(V);
1456 return getCI(&Ty, LI.getAlign().value());
1457}
1458
1461 auto &LI = cast<LoadInst>(V);
1462 return getCI(&Ty, LI.getType()->getTypeID());
1463}
1464
1466 InstrumentationConfig &IConf,
1468 auto &LI = cast<LoadInst>(V);
1469 return getSubTypeID(*LI.getType(), Ty);
1470}
1471
1473 InstrumentationConfig &IConf,
1475 auto &LI = cast<LoadInst>(V);
1476 return getCI(&Ty, uint64_t(LI.getOrdering()));
1477}
1478
1481 auto &LI = cast<LoadInst>(V);
1482 return getCI(&Ty, uint64_t(LI.getSyncScopeID()));
1483}
1484
1487 auto &LI = cast<LoadInst>(V);
1488 return getCI(&Ty, LI.isVolatile());
1489}
1490
1492 InstrumentorIRBuilderTy &IIRB, ConfigTy *UserConfig) {
1493 if (UserConfig)
1494 Config = *UserConfig;
1495 if (Config.has(PassPointer))
1496 IRTArgs.push_back(IRTArg(IIRB.PtrTy, "base_pointer",
1497 "The base pointer in question.",
1499 if (Config.has(PassPointerKind))
1500 IRTArgs.push_back(IRTArg(
1501 IIRB.Int32Ty, "base_pointer_kind",
1502 "The base pointer kind (argument, global, instruction, unknown).",
1504 addCommonArgs(IConf, IIRB.Ctx, Config.has(PassId));
1505 IConf.addChoice(*this, IIRB.Ctx);
1506}
1507
1509 InstrumentationConfig &IConf,
1511 if (isa<Argument>(V))
1512 return getCI(&Ty, 0);
1513 if (isa<GlobalValue>(V))
1514 return getCI(&Ty, 1);
1515 if (isa<Instruction>(V))
1516 return getCI(&Ty, 2);
1517 return getCI(&Ty, 3);
1518}
1519
1521 ConfigTy *UserConfig) {
1522 if (UserConfig)
1523 Config = *UserConfig;
1524
1525 if (Config.has(PassName))
1526 IRTArgs.push_back(IRTArg(IIRB.PtrTy, "module_name",
1527 "The module/translation unit name.",
1529 if (Config.has(PassTargetTriple))
1530 IRTArgs.push_back(IRTArg(IIRB.PtrTy, "target_triple", "The target triple.",
1532
1533 addCommonArgs(IConf, IIRB.Ctx, Config.has(PassId));
1534 IConf.addChoice(*this, IIRB.Ctx);
1535}
1538 // V is a constructor or destructor of the module we can place code in.
1539 auto &Fn = cast<Function>(V);
1540 return IConf.getGlobalString(Fn.getParent()->getName(), IIRB);
1541}
1543 InstrumentationConfig &IConf,
1545 // V is a constructor or destructor of the module we can place code in.
1546 auto &Fn = cast<Function>(V);
1547 return IConf.getGlobalString(Fn.getParent()->getTargetTriple().getTriple(),
1548 IIRB);
1549}
1550
1552 InstrumentorIRBuilderTy &IIRB, ConfigTy *UserConfig) {
1553 if (UserConfig)
1554 Config = *UserConfig;
1556 if (Config.has(PassAddress))
1557 IRTArgs.push_back(IRTArg(
1558 IIRB.PtrTy, "address",
1559 "The address of the global (replaceable for definitions).",
1562 if (Config.has(PassAS))
1563 IRTArgs.push_back(IRTArg(IIRB.Int32Ty, "address_space",
1564 "The address space of the global.", IRTArg::NONE,
1565 getAS));
1566 if (Config.has(PassDeclaredSize))
1567 IRTArgs.push_back(IRTArg(IIRB.Int64Ty, "declared_size",
1568 "The size of the declared type of the global.",
1570 if (Config.has(PassAlignment))
1571 IRTArgs.push_back(IRTArg(IIRB.Int64Ty, "alignment",
1572 "The allocation alignment.", IRTArg::NONE,
1573 getAlignment));
1574 if (Config.has(PassName))
1575 IRTArgs.push_back(IRTArg(IIRB.PtrTy, "name", "The name of the global.",
1577 if (Config.has(PassInitialValue))
1578 IRTArgs.push_back(IRTArg(
1579 IIRB.Int64Ty, "initial_value", "The initial value of the global.",
1582 if (Config.has(PassIsConstant))
1583 IRTArgs.push_back(IRTArg(IIRB.Int8Ty, "is_constant",
1584 "Flag to indicate constant globals.", IRTArg::NONE,
1585 isConstant));
1586 if (Config.has(PassIsDefinition))
1587 IRTArgs.push_back(IRTArg(IIRB.Int8Ty, "is_definition",
1588 "Flag to indicate global definitions.",
1590 addCommonArgs(IConf, IIRB.Ctx, Config.has(PassId));
1591 IConf.addChoice(*this, IIRB.Ctx);
1592}
1596 if (GV.getAddressSpace())
1597 return ConstantExpr::getAddrSpaceCast(&GV, IIRB.PtrTy);
1598 return &GV;
1599}
1601 InstrumentationConfig &IConf,
1604
1605 GlobalVariable *ShadowGV = nullptr;
1606 auto ShadowName = IConf.getRTName("shadow.", GV.getName());
1607 auto &DL = GV.getDataLayout();
1608 if (GV.isDeclaration()) {
1609 ShadowGV = new GlobalVariable(*GV.getParent(), GV.getType(), false,
1611 ShadowName, &GV, GV.getThreadLocalMode(),
1612 DL.getDefaultGlobalsAddressSpace());
1613 } else {
1614 ShadowGV = new GlobalVariable(
1615 *GV.getParent(), NewV.getType(), false, GV.getLinkage(),
1616 PoisonValue::get(NewV.getType()), ShadowName, &GV);
1617 IIRB.IRB.CreateStore(&NewV, ShadowGV);
1618 }
1619
1623 DenseMap<Value *, Instruction *> ConstToInstMap;
1625
1626 auto MakeInstForConst = [&](Use &U) {
1627 Instruction *&I = ConstToInstMap[U];
1628 if (I)
1629 return;
1630 if (U == &GV) {
1631 } else if (auto *CE = dyn_cast<ConstantExpr>(U)) {
1632 I = CE->getAsInstruction();
1633 }
1634 };
1635
1636 auto InsertConsts = [&](Instruction *UserI, Use &UserU) {
1638 auto *&Reload = ReloadMap[UserI->getFunction()];
1639 if (!Reload) {
1640 Reload = new LoadInst(
1641 GV.getType(), ShadowGV, GV.getName() + ".shadow_load",
1643 IIRB.NewInsts.insert({Reload, IIRB.Epoch});
1644 }
1645 Worklist.push_back({UserI, &UserU});
1646 while (!Worklist.empty()) {
1647 auto [I, U] = Worklist.pop_back_val();
1648 if (*U == &GV) {
1649 U->set(ReloadMap[I->getFunction()]);
1650 continue;
1651 }
1652 if (auto *CI = ConstToInstMap[*U]) {
1653 auto *CIClone = CI->clone();
1654 IIRB.NewInsts.insert({CIClone, IIRB.Epoch});
1655 if (auto *PHI = dyn_cast<PHINode>(I)) {
1656 auto *BB = PHI->getIncomingBlock(U->getOperandNo());
1657 CIClone->insertBefore(BB->getTerminator()->getIterator());
1658 } else {
1659 CIClone->insertBefore(I->getIterator());
1660 }
1661 U->set(CIClone);
1662 for (auto &CICUse : CIClone->operands()) {
1663 Worklist.push_back({CIClone, &CICUse});
1664 }
1665 }
1666 }
1667 };
1668
1669 SmallPtrSet<Use *, 8> Visited;
1670 while (!Worklist.empty()) {
1671 Use *U = Worklist.pop_back_val();
1672 if (!Done.insert(U).second)
1673 continue;
1674 MakeInstForConst(*U);
1675 auto *I = dyn_cast<Instruction>(U->getUser());
1676 if (!I) {
1677 append_range(Worklist, make_pointer_range(U->getUser()->uses()));
1678 continue;
1679 }
1680 if (IIRB.NewInsts.lookup(I) == IIRB.Epoch)
1681 continue;
1683 continue;
1684 if (auto *II = dyn_cast<IntrinsicInst>(I))
1685 if (II->getIntrinsicID() == Intrinsic::eh_typeid_for)
1686 continue;
1687 if (I->getParent())
1688 InsertConsts(I, *U);
1689 }
1690
1691 for (auto &It : ConstToInstMap)
1692 if (It.second)
1693 It.second->deleteValue();
1694
1695 return &V;
1696}
1700 return getCI(&Ty, GV.getAddressSpace());
1701}
1703 InstrumentationConfig &IConf,
1706 MaybeAlign Alignment = GV.getAlign();
1707 return getCI(&Ty, Alignment ? Alignment->value() : 0);
1708}
1710 InstrumentationConfig &IConf,
1713 auto &DL = GV.getDataLayout();
1714 return getCI(&Ty, DL.getTypeAllocSize(GV.getValueType()));
1715}
1717 InstrumentationConfig &IConf,
1720 return IConf.getGlobalString(GV.getName(), IIRB);
1721}
1732 return getCI(&Ty, GV.isConstant());
1733}
1735 InstrumentationConfig &IConf,
1738 return getCI(&Ty, !GV.isDeclaration());
1739}
1740
1741/// CastIO
1742/// {
1744 ConfigTy *UserConfig) {
1745 if (UserConfig)
1746 Config = *UserConfig;
1748 if (Config.has(PassInput))
1749 IRTArgs.push_back(
1750 IRTArg(IIRB.Int64Ty, "input", "Input value of the cast.",
1753 : IRTArg::NONE),
1754 getInput));
1755 if (Config.has(PassInputTypeId))
1756 IRTArgs.push_back(IRTArg(IIRB.Int32Ty, "input_type_id",
1757 "The type id of the input value.", IRTArg::TYPEID,
1759 if (Config.has(PassInputSubTypeId))
1760 IRTArgs.push_back(IRTArg(
1761 IIRB.Int32Ty, "input_sub_type_id",
1762 "The sub type id of the input value (for arrays and vectors, or -1).",
1764 if (Config.has(PassInputSize))
1765 IRTArgs.push_back(IRTArg(IIRB.Int32Ty, "input_size",
1766 "The size of the input value.", IRTArg::NONE,
1767 getInputSize));
1768 if (!IsPRE && Config.has(PassResult))
1769 IRTArgs.push_back(
1770 IRTArg(IIRB.Int64Ty, "result", "Result of the cast.",
1773 : IRTArg::NONE),
1774 getValue, Config.has(ReplaceResult) ? replaceValue : nullptr));
1775 if (Config.has(PassResultTypeId))
1776 IRTArgs.push_back(IRTArg(IIRB.Int32Ty, "result_type_id",
1777 "The type id of the result value.", IRTArg::TYPEID,
1779 if (Config.has(PassResultSubTypeId))
1780 IRTArgs.push_back(IRTArg(
1781 IIRB.Int32Ty, "result_sub_type_id",
1782 "The sub type id of the result value (for arrays and vectors, or -1).",
1784 if (Config.has(PassResultSize))
1785 IRTArgs.push_back(IRTArg(IIRB.Int32Ty, "result_size",
1786 "The size of the result value.", IRTArg::NONE,
1787 getResultSize));
1788 if (Config.has(PassOpcode))
1789 IRTArgs.push_back(IRTArg(IIRB.Int32Ty, "opcode",
1790 "The opcode of the cast instruction.",
1792
1793 addCommonArgs(IConf, IIRB.Ctx, Config.has(PassId));
1794 IConf.addChoice(*this, IIRB.Ctx);
1795}
1796
1799 auto &CI = cast<CastInst>(V);
1800 return CI.getOperand(0);
1801}
1802
1805 auto &CI = cast<CastInst>(V);
1806 return getCI(&Ty, CI.getSrcTy()->getTypeID());
1807}
1808
1810 InstrumentationConfig &IConf,
1812 auto &CI = cast<CastInst>(V);
1813 return getSubTypeID(*CI.getSrcTy(), Ty);
1814}
1815
1818 auto &CI = cast<CastInst>(V);
1819 auto &DL = CI.getDataLayout();
1820 return getCI(&Ty, DL.getTypeStoreSize(CI.getSrcTy()));
1821}
1822
1825 auto &CI = cast<CastInst>(V);
1826 return getCI(&Ty, CI.getDestTy()->getTypeID());
1827}
1828
1830 InstrumentationConfig &IConf,
1832 auto &CI = cast<CastInst>(V);
1833 return getSubTypeID(*CI.getDestTy(), Ty);
1834}
1835
1838 auto &CI = cast<CastInst>(V);
1839 auto &DL = CI.getDataLayout();
1840 return getCI(&Ty, DL.getTypeStoreSize(CI.getDestTy()));
1841}
1842///}
1843
1846 auto &I = cast<Instruction>(V);
1847 uint64_t Flag = NUMERIC_FLAG_NONE;
1848
1849 switch (I.getOpcode()) {
1850 case Instruction::Add:
1851 case Instruction::Sub:
1852 case Instruction::Mul:
1853 case Instruction::Shl:
1854 if (I.hasNoSignedWrap())
1856 if (I.hasNoUnsignedWrap())
1858 break;
1859 case Instruction::FAdd:
1860 case Instruction::FSub:
1861 case Instruction::FMul:
1862 case Instruction::FDiv:
1863 case Instruction::FNeg:
1864 if (I.hasNoNaNs())
1866 if (I.hasNoInfs())
1868 if (I.hasNoSignedZeros())
1870 break;
1871 case Instruction::AShr:
1872 case Instruction::LShr:
1873 case Instruction::SDiv:
1874 case Instruction::UDiv:
1875 if (I.isExact())
1876 Flag |= NUMERIC_FLAG_IS_EXACT;
1877 break;
1878 }
1879
1880 if (auto *DI = dyn_cast<PossiblyDisjointInst>(&V))
1881 if (DI->isDisjoint())
1883
1884 return getCI(&Ty, Flag);
1885}
1886
1895
1897 InstrumentorIRBuilderTy &IIRB, ConfigTy *UserConfig) {
1898 if (UserConfig)
1899 Config = UserConfig;
1901 const auto ValArgOpts =
1904 if (Config.has(PassTypeId))
1905 IRTArgs.push_back(IRTArg(IIRB.Int32Ty, "type_id",
1906 "The operation's type id.", IRTArg::TYPEID,
1907 getTypeId));
1908 if (Config.has(PassSubTypeId))
1909 IRTArgs.push_back(
1910 IRTArg(IIRB.Int32Ty, "sub_type_id",
1911 "The operation's sub type id (for arrays and vectors, or -1).",
1913 if (Config.has(PassSize))
1914 IRTArgs.push_back(IRTArg(IIRB.Int32Ty, "size", "The operation's type size.",
1916 if (Config.has(PassOpcode))
1917 IRTArgs.push_back(IRTArg(IIRB.Int32Ty, "opcode", "The instruction opcode.",
1919 if (Config.has(PassLeft))
1920 IRTArgs.push_back(IRTArg(IIRB.Int64Ty, "left",
1921 "The operation's left operand.", ValArgOpts,
1923 if (Config.has(PassRight))
1924 IRTArgs.push_back(IRTArg(IIRB.Int64Ty, "right",
1925 "The operation's right operand. This value is "
1926 "poison for unary operations.",
1927 ValArgOpts, getRightOperand));
1928 if (!IsPRE && Config.has(PassResult))
1929 IRTArgs.push_back(
1930 IRTArg(IIRB.Int64Ty, "result", "Result of the operation.",
1931 IRTArg::REPLACABLE | ValArgOpts, getValue,
1932 Config.has(ReplaceResult) ? replaceValue : nullptr));
1933 if (Config.has(PassFlags))
1934 IRTArgs.push_back(
1935 IRTArg(IIRB.Int64Ty, "flags",
1936 "A bitmask value signaling which instruction flags are present.",
1938 addCommonArgs(IConf, IIRB.Ctx, Config.has(PassId));
1939 addFlagNames();
1940 IConf.addChoice(*this, IIRB.Ctx);
1941}
1942
1944 InstrumentationConfig &IConf,
1946 auto &I = cast<Instruction>(V);
1947 return getCI(&Ty, I.getOperand(0)->getType()->getTypeID());
1948}
1949
1951 InstrumentationConfig &IConf,
1953 auto &I = cast<Instruction>(V);
1954 auto &DL = I.getDataLayout();
1955 return getCI(&Ty, DL.getTypeStoreSize(I.getOperand(0)->getType()));
1956}
1957
1960 auto *CI = dyn_cast<CmpInst>(&V);
1961 return getCI(&Ty, CI->getPredicate());
1962}
1963
1970
1973 auto &I = cast<Instruction>(V);
1974 uint64_t Flag = NUMERIC_FLAG_NONE;
1975
1976 switch (I.getOpcode()) {
1977 case Instruction::ICmp:
1978 if (dyn_cast<ICmpInst>(&V)->hasSameSign())
1979 Flag |= COMPARE_FLAG_SAMESIGN;
1980 break;
1981 case Instruction::FCmp:
1982 if (I.hasNoNaNs())
1984 if (I.hasNoInfs())
1986 if (I.hasNoSignedZeros())
1988 break;
1989 }
1990
1991 return getCI(&Ty, Flag);
1992}
1993
1995 InstrumentorIRBuilderTy &IIRB, ConfigTy *UserConfig) {
1996 if (UserConfig)
1997 Config = UserConfig;
1999 const auto OperandArgOpts =
2002 if (Config.has(PassOpTypeId))
2003 IRTArgs.push_back(IRTArg(IIRB.Int32Ty, "operand_type_id",
2004 "The operand type id.", IRTArg::NONE,
2006 if (Config.has(PassOpSize))
2007 IRTArgs.push_back(IRTArg(IIRB.Int32Ty, "operand_size",
2008 "The operand type size.", IRTArg::NONE,
2010 if (Config.has(PassOpcode))
2011 IRTArgs.push_back(IRTArg(IIRB.Int32Ty, "opcode", "The instruction opcode.",
2013 if (Config.has(PassPredicate))
2014 IRTArgs.push_back(IRTArg(IIRB.Int32Ty, "predicate",
2015 "The comparison predicate ID.", IRTArg::NONE,
2016 getPredicate));
2017 if (Config.has(PassLeft))
2018 IRTArgs.push_back(IRTArg(IIRB.Int64Ty, "left",
2019 "The comparison's left operand.", OperandArgOpts,
2021 if (Config.has(PassRight))
2022 IRTArgs.push_back(IRTArg(IIRB.Int64Ty, "right",
2023 "The comparison's right operand.", OperandArgOpts,
2025 if (!IsPRE && Config.has(PassResultSize))
2026 IRTArgs.push_back(IRTArg(IIRB.Int32Ty, "result_type_id",
2027 "The result value's type ID.", IRTArg::NONE,
2028 getTypeId));
2029 if (!IsPRE && Config.has(PassResultSize))
2030 IRTArgs.push_back(IRTArg(IIRB.Int32Ty, "result_size",
2031 "Size of the result value.", IRTArg::NONE,
2032 getTypeSize));
2033 if (!IsPRE && Config.has(PassResult))
2034 IRTArgs.push_back(
2035 IRTArg(IIRB.Int64Ty, "result", "Result of the operation.",
2038 : IRTArg::NONE),
2039 getValue, Config.has(ReplaceResult) ? replaceValue : nullptr));
2040 if (Config.has(PassFlags))
2041 IRTArgs.push_back(
2042 IRTArg(IIRB.Int64Ty, "flags",
2043 "A bitmask value signaling which instruction flags are present.",
2045 addFlagNames();
2046 addCommonArgs(IConf, IIRB.Ctx, Config.has(PassId));
2047 IConf.addChoice(*this, IIRB.Ctx);
2048}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file defines the StringMap class.
unsigned 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
Machine Check Debug Module
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.
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 getFirstNonPHIOrDbgOrAlloca() const
Returns an iterator to the first instruction in this block that is not a PHINode, a debug intrinsic,...
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:43
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:794
const DataLayout & getDataLayout() const
Get the data layout of the module this function belongs to.
Definition Function.cpp:360
iterator_range< arg_iterator > args()
Definition Function.h:877
arg_iterator arg_begin()
Definition Function.h:853
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:356
size_t arg_size() const
Definition Function.h:886
Argument * getArg(unsigned i) const
Definition Function.h:871
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
Definition Function.cpp:734
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:68
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
StringRef getName() const
Get a short "name" for the module.
Definition Module.h:316
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
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:581
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:561
iterator_range< use_iterator > uses()
Definition Value.h:382
bool hasName() const
Definition Value.h:263
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
Definition Value.cpp:319
An efficient, type-erasing, non-owning reference to a callable.
Changed
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
initializer< Ty > init(const Ty &Val)
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
bool internalizeModule(Module &TheModule, std::function< bool(const GlobalValue &)> MustPreserveGV)
Helper function to internalize functions and variables in a Module.
Definition Internalize.h:78
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
constexpr uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition Alignment.h:144
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.
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:106
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 > 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.
std::unique_ptr< BaseConfigurationOption > RuntimeBitcode
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
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