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, 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,
733 IIRB.IRB.GetInsertBlock()->getDataLayout());
734}
735
739 if (V.getType()->isVoidTy())
740 return &V;
741
742 auto *NewVCasted = &NewV;
743 if (auto *I = dyn_cast<Instruction>(&NewV)) {
745 IIRB.IRB.SetInsertPoint(I->getNextNode());
746 ensureDbgLoc(IIRB.IRB);
747 NewVCasted = tryToCast(IIRB.IRB, &NewV, V.getType(), IIRB.DL,
748 /*AllowTruncate=*/true);
749 }
750 V.replaceUsesWithIf(NewVCasted, [&](Use &U) {
751 if (IIRB.NewInsts.lookup(cast<Instruction>(U.getUser())) == IIRB.Epoch)
752 return false;
753 return !isa<LifetimeIntrinsic>(U.getUser()) && !U.getUser()->isDroppable();
754 });
755
756 return &V;
757}
758
760 Type *RetTy)
761 : IO(IO), RetTy(RetTy) {
762 for (auto &It : IO.IRTArgs) {
763 if (!It.Enabled)
764 continue;
765 NumReplaceableArgs += bool(It.Flags & IRTArg::REPLACABLE);
766 MightRequireIndirection |= It.Flags & IRTArg::POTENTIALLY_INDIRECT;
767 }
770}
771
774 const DataLayout &DL, bool ForceIndirection) {
775 assert(((ForceIndirection && MightRequireIndirection) ||
776 (!ForceIndirection && !RequiresIndirection)) &&
777 "Wrong indirection setting!");
778
779 SmallVector<Type *> ParamTypes;
780 for (auto &It : IO.IRTArgs) {
781 if (!It.Enabled)
782 continue;
783 if (!ForceIndirection || !isPotentiallyIndirect(It)) {
784 ParamTypes.push_back(It.Ty);
785 if (!RetTy && NumReplaceableArgs == 1 && (It.Flags & IRTArg::REPLACABLE))
786 RetTy = It.Ty;
787 continue;
788 }
789
790 // The indirection pointer and the size of the value.
791 ParamTypes.push_back(IIRB.PtrTy);
792 if (!(It.Flags & IRTArg::INDIRECT_HAS_SIZE))
793 ParamTypes.push_back(IIRB.Int32Ty);
794 }
795 if (!RetTy)
796 RetTy = IIRB.VoidTy;
797
798 return FunctionType::get(RetTy, ParamTypes, /*isVarArg=*/false);
799}
800
804 const DataLayout &DL,
805 InstrumentationCaches &ICaches) {
806 SmallVector<Value *> CallParams;
807
809 auto IP = IIRB.IRB.GetInsertPoint();
810
811 bool ForceIndirection = RequiresIndirection;
812 for (auto &It : IO.IRTArgs) {
813 if (!It.Enabled)
814 continue;
815 auto *&Param = ICaches.DirectArgCache[{IIRB.Epoch, IO.getName(), It.Name}];
816 if (!Param || It.NoCache)
817 // Avoid passing the caches to the getter.
818 Param = It.GetterCB(*V, *It.Ty, IConf, IIRB);
819 assert(Param);
820
821 if (Param->getType()->isVoidTy()) {
822 Param = Constant::getNullValue(It.Ty);
823 } else if (Param->getType()->isAggregateType() ||
824 Param->getType()->isVectorTy() ||
825 DL.getTypeSizeInBits(Param->getType()) >
826 DL.getTypeSizeInBits(It.Ty)) {
827 if (!isPotentiallyIndirect(It)) {
829 Twine("indirection needed for ") + It.Name + Twine(" in ") +
830 IO.getName() +
831 Twine(", but not indicated. Instrumentation is skipped"),
832 DS_Warning));
833 return nullptr;
834 }
835 ForceIndirection = true;
836 } else {
837 Param = tryToCast(IIRB.IRB, Param, It.Ty, DL);
838 }
839 CallParams.push_back(Param);
840 }
841
842 if (ForceIndirection) {
843 Function *Fn = IIRB.IRB.GetInsertBlock()->getParent();
844
845 unsigned Offset = 0;
846 for (auto &It : IO.IRTArgs) {
847 if (!It.Enabled)
848 continue;
849
850 if (!isPotentiallyIndirect(It)) {
851 ++Offset;
852 continue;
853 }
854 auto *&CallParam = CallParams[Offset++];
855 if (!(It.Flags & IRTArg::INDIRECT_HAS_SIZE)) {
856 CallParams.insert(&CallParam + 1, IIRB.IRB.getInt32(DL.getTypeStoreSize(
857 CallParam->getType())));
858 Offset += 1;
859 }
860
861 auto *&CachedParam =
862 ICaches.IndirectArgCache[{IIRB.Epoch, IO.getName(), It.Name}];
863 if (CachedParam) {
864 CallParam = CachedParam;
865 continue;
866 }
867
868 auto *AI = IIRB.getAlloca(Fn, CallParam->getType());
869 IIRB.IRB.CreateStore(CallParam, AI);
870 CallParam = CachedParam = tryToCast(IIRB.IRB, AI, IIRB.PtrTy, DL);
871 }
872 }
873
874 if (!ForceIndirection)
875 IIRB.IRB.SetInsertPoint(IP);
876 ensureDbgLoc(IIRB.IRB);
877
878 auto *FnTy = createLLVMSignature(IConf, IIRB, DL, ForceIndirection);
879 auto CompleteName =
880 IConf.getRTName(IO.IP.isPRE() ? "pre_" : "post_", IO.getName(),
881 ForceIndirection ? "_ind" : "");
882 auto FC = IIRB.IRB.GetInsertBlock()->getModule()->getOrInsertFunction(
883 CompleteName, FnTy);
884 auto *CI = IIRB.IRB.CreateCall(FC, CallParams);
885 CI->addFnAttr(Attribute::get(IIRB.Ctx, Attribute::WillReturn));
886
887 for (unsigned I = 0, E = IO.IRTArgs.size(); I < E; ++I) {
888 if (!IO.IRTArgs[I].Enabled)
889 continue;
890 if (!isReplacable(IO.IRTArgs[I]))
891 continue;
892 bool IsCustomReplaceable = IO.IRTArgs[I].Flags & IRTArg::REPLACABLE_CUSTOM;
893 Value *NewValue = FnTy->isVoidTy() || IsCustomReplaceable
894 ? ICaches.DirectArgCache[{IIRB.Epoch, IO.getName(),
895 IO.IRTArgs[I].Name}]
896 : CI;
897 assert(NewValue);
898 if (ForceIndirection && !IsCustomReplaceable &&
899 isPotentiallyIndirect(IO.IRTArgs[I])) {
900 auto *Q =
901 ICaches
902 .IndirectArgCache[{IIRB.Epoch, IO.getName(), IO.IRTArgs[I].Name}];
903 NewValue = IIRB.IRB.CreateLoad(V->getType(), Q);
904 }
905 V = IO.IRTArgs[I].SetterCB(*V, *NewValue, IConf, IIRB);
906 }
907 return CI;
908}
909
910template <typename Ty> constexpr static Value *getValue(Ty &ValueOrUse) {
911 if constexpr (std::is_same<Ty, Use>::value)
912 return ValueOrUse.get();
913 else
914 return static_cast<Value *>(&ValueOrUse);
915}
916
917template <typename Range>
920 auto *Fn = IIRB.IRB.GetInsertBlock()->getParent();
921 auto *I32Ty = IIRB.IRB.getInt32Ty();
922 SmallVector<Constant *> ConstantValues;
925 for (auto &RE : R) {
926 Value *V = getValue(RE);
927 if (!V->getType()->isSized())
928 continue;
929 auto VSize = IIRB.DL.getTypeAllocSize(V->getType());
930 ConstantValues.push_back(getCI(I32Ty, VSize));
931 Types.push_back(I32Ty);
932 ConstantValues.push_back(getCI(I32Ty, V->getType()->getTypeID()));
933 Types.push_back(I32Ty);
934 if (uint32_t MisAlign = VSize % 8) {
935 Types.push_back(ArrayType::get(IIRB.Int8Ty, 8 - MisAlign));
936 ConstantValues.push_back(ConstantArray::getNullValue(Types.back()));
937 }
938 Types.push_back(V->getType());
939 if (auto *C = dyn_cast<Constant>(V)) {
940 ConstantValues.push_back(C);
941 continue;
942 }
943 Values.push_back({V, ConstantValues.size()});
944 ConstantValues.push_back(Constant::getNullValue(V->getType()));
945 }
946 if (Types.empty())
947 return ConstantPointerNull::get(IIRB.PtrTy);
948
949 StructType *STy = StructType::get(Fn->getContext(), Types, /*isPacked=*/true);
950 Constant *Initializer = ConstantStruct::get(STy, ConstantValues);
951
952 GlobalVariable *&GV = IConf.ConstantGlobalsCache[Initializer];
953 if (!GV)
954 GV = new GlobalVariable(*Fn->getParent(), STy, false,
955 GlobalValue::InternalLinkage, Initializer,
956 IConf.getRTName("", "value_pack"));
957
958 auto *AI = IIRB.getAlloca(Fn, STy);
959 IIRB.IRB.CreateMemCpy(AI, AI->getAlign(), GV, GV->getAlign(),
960 IIRB.DL.getTypeAllocSize(STy));
961 for (auto [Param, Idx] : Values) {
962 auto *Ptr = IIRB.IRB.CreateStructGEP(STy, AI, Idx);
963 IIRB.IRB.CreateStore(Param, Ptr);
964 }
965 return AI;
966}
967
968template <typename Range>
969static void readValuePack(const Range &R, Value &Pack,
971 function_ref<void(int, Value *)> SetterCB) {
972 auto *Fn = IIRB.IRB.GetInsertBlock()->getParent();
973 auto &DL = Fn->getDataLayout();
974 SmallVector<Value *> ParameterValues;
975 unsigned Offset = 0;
976 for (const auto &[Idx, RE] : enumerate(R)) {
977 Value *V = getValue(RE);
978 if (!V->getType()->isSized())
979 continue;
980 Offset += 8;
981 auto VSize = DL.getTypeAllocSize(V->getType());
982 auto Padding = alignTo(VSize, 8) - VSize;
983 Offset += Padding;
984 auto *Ptr = IIRB.IRB.CreateConstInBoundsGEP1_32(IIRB.Int8Ty, &Pack, Offset);
985 auto *NewV = IIRB.IRB.CreateLoad(V->getType(), Ptr);
986 SetterCB(Idx, NewV);
987 Offset += VSize;
988 }
989}
990
994 auto &I = cast<Instruction>(V);
995 return getCI(&Ty, I.getOpcode());
996}
997
1001 auto &I = cast<Instruction>(V);
1002 auto &DL = I.getDataLayout();
1003 return getCI(&Ty, DL.getTypeStoreSize(V.getType()));
1004}
1005
1007 InstrumentationConfig &IConf,
1009 auto &I = cast<Instruction>(V);
1010 return I.getOperand(0);
1011}
1012
1014 InstrumentationConfig &IConf,
1016 auto &I = cast<Instruction>(V);
1017 if (I.getNumOperands() > 1)
1018 return I.getOperand(1);
1019 return PoisonValue::get(&Ty);
1020}
1021
1023 InstrumentationConfig &IConf,
1025 return getCI(&Ty, V.getType()->getTypeID());
1026}
1027
1029 InstrumentationConfig &IConf,
1031 return getSubTypeID(*V.getType(), Ty);
1032}
1033
1034/// FunctionIO
1035/// {
1037 InstrumentorIRBuilderTy &IIRB, ConfigTy *UserConfig) {
1038 using namespace std::placeholders;
1039 if (UserConfig)
1040 Config = *UserConfig;
1041
1043 if (Config.has(PassAddress))
1044 IRTArgs.push_back(IRTArg(IIRB.PtrTy, "address", "The function address.",
1046 if (Config.has(PassName))
1047 IRTArgs.push_back(IRTArg(IIRB.PtrTy, "name", "The function name.",
1049 if (Config.has(PassNumArguments))
1050 IRTArgs.push_back(
1051 IRTArg(IIRB.Int32Ty, "num_arguments",
1052 "Number of function arguments (without varargs).", IRTArg::NONE,
1053 std::bind(&FunctionIO::getNumArguments, this, _1, _2, _3, _4)));
1054 if (Config.has(PassArguments))
1055 IRTArgs.push_back(IRTArg(
1056 IIRB.PtrTy, "arguments", "Description of the arguments.",
1058 : IRTArg::NONE) |
1060 std::bind(&FunctionIO::getArguments, this, _1, _2, _3, _4),
1061 std::bind(&FunctionIO::setArguments, this, _1, _2, _3, _4)));
1062 if (Config.has(PassIsMain))
1063 IRTArgs.push_back(IRTArg(IIRB.Int8Ty, "is_main",
1064 "Flag to indicate it is the main function.",
1066 addCommonArgs(IConf, IIRB.Ctx, Config.has(PassId));
1067 IConf.addChoice(*this, IIRB.Ctx);
1068}
1069
1071 InstrumentationConfig &IConf,
1073 auto &Fn = cast<Function>(V);
1074 if (Fn.isIntrinsic())
1075 return Constant::getNullValue(&Ty);
1076 return &V;
1077}
1079 InstrumentationConfig &IConf,
1081 auto &Fn = cast<Function>(V);
1082 return IConf.getGlobalString(IConf.DemangleFunctionNames->getBool()
1083 ? demangle(Fn.getName())
1084 : Fn.getName(),
1085 IIRB);
1086}
1088 InstrumentationConfig &IConf,
1090 auto &Fn = cast<Function>(V);
1091 if (!Config.ArgFilter)
1092 return getCI(&Ty, Fn.arg_size());
1093 auto FRange = make_filter_range(Fn.args(), Config.ArgFilter);
1094 return getCI(&Ty, std::distance(FRange.begin(), FRange.end()));
1095}
1097 InstrumentationConfig &IConf,
1099 auto &Fn = cast<Function>(V);
1100 if (!Config.ArgFilter)
1101 return createValuePack(Fn.args(), IConf, IIRB);
1102 return createValuePack(make_filter_range(Fn.args(), Config.ArgFilter), IConf,
1103 IIRB);
1104}
1106 InstrumentationConfig &IConf,
1108 auto &Fn = cast<Function>(V);
1109 auto *AIt = Fn.arg_begin();
1110 auto CB = [&](int Idx, Value *ReplV) {
1111 while (Config.ArgFilter && !Config.ArgFilter(*AIt))
1112 ++AIt;
1113 Fn.getArg(Idx)->replaceUsesWithIf(ReplV, [&](Use &U) {
1114 return IIRB.NewInsts.lookup(cast<Instruction>(U.getUser())) != IIRB.Epoch;
1115 });
1116 ++AIt;
1117 };
1118 if (!Config.ArgFilter)
1119 readValuePack(Fn.args(), NewV, IIRB, CB);
1120 else
1121 readValuePack(make_filter_range(Fn.args(), Config.ArgFilter), NewV, IIRB,
1122 CB);
1123 return &Fn;
1124}
1126 InstrumentationConfig &IConf,
1128 auto &Fn = cast<Function>(V);
1129 return getCI(&Ty, Fn.getName() == "main");
1130}
1131
1132/// UnreachableIO
1133///{
1135 InstrumentorIRBuilderTy &IIRB, ConfigTy *UserConfig) {
1136 if (UserConfig)
1137 Config = *UserConfig;
1138 addCommonArgs(IConf, IIRB.Ctx, Config.has(PassId));
1139 IConf.addChoice(*this, IIRB.Ctx);
1140}
1141///}
1142
1143/// AllocaIO
1144///{
1146 ConfigTy *UserConfig) {
1147 if (UserConfig)
1148 Config = *UserConfig;
1149
1151 if (!IsPRE && Config.has(PassAddress))
1152 IRTArgs.push_back(
1153 IRTArg(IIRB.PtrTy, "address", "The allocated memory address.",
1157 if (Config.has(PassSize))
1158 IRTArgs.push_back(IRTArg(
1159 IIRB.Int64Ty, "size", "The allocation size.",
1161 getSize, setSize));
1162 if (Config.has(PassAlignment))
1163 IRTArgs.push_back(IRTArg(IIRB.Int64Ty, "alignment",
1164 "The allocation alignment.", IRTArg::NONE,
1165 getAlignment));
1166
1167 addCommonArgs(IConf, IIRB.Ctx, Config.has(PassId));
1168 IConf.addChoice(*this, IIRB.Ctx);
1169}
1170
1173 auto &AI = cast<AllocaInst>(V);
1174 return IIRB.IRB.CreateAllocationSize(&Ty, &AI);
1175}
1176
1179 auto &AI = cast<AllocaInst>(V);
1180 const DataLayout &DL = AI.getDataLayout();
1181 auto *NewAI = IIRB.IRB.CreateAlloca(IIRB.IRB.getInt8Ty(),
1182 DL.getAllocaAddrSpace(), &NewV);
1183 NewAI->setAlignment(AI.getAlign());
1184 AI.replaceAllUsesWith(NewAI);
1185 IIRB.eraseLater(&AI);
1186 return NewAI;
1187}
1188
1191 return getCI(&Ty, cast<AllocaInst>(V).getAlign().value());
1192}
1193///}
1194
1196 ConfigTy *UserConfig) {
1197 if (UserConfig)
1198 Config = *UserConfig;
1199
1201 if (Config.has(PassPointer)) {
1202 IRTArgs.push_back(
1203 IRTArg(IIRB.PtrTy, "pointer", "The accessed pointer.",
1204 ((IsPRE && Config.has(ReplacePointer)) ? IRTArg::REPLACABLE
1205 : IRTArg::NONE),
1207 }
1208 if (Config.has(PassPointerAS)) {
1209 IRTArgs.push_back(IRTArg(IIRB.Int32Ty, "pointer_as",
1210 "The address space of the accessed pointer.",
1212 }
1213 if (Config.has(PassBasePointerInfo)) {
1214 IRTArgs.push_back(IRTArg(IIRB.PtrTy, "base_pointer_info",
1215 "The runtime provided base pointer info.",
1217 }
1218 if (Config.has(PassStoredValue)) {
1219 IRTArgs.push_back(
1220 IRTArg(getValueType(IIRB), "value", "The stored value.",
1223 : IRTArg::NONE),
1224 getValue));
1225 }
1226 if (Config.has(PassStoredValueSize)) {
1227 IRTArgs.push_back(IRTArg(IIRB.Int64Ty, "value_size",
1228 "The size of the stored value.", IRTArg::NONE,
1229 getValueSize));
1230 }
1231 if (Config.has(PassAlignment)) {
1232 IRTArgs.push_back(IRTArg(IIRB.Int64Ty, "alignment",
1233 "The known access alignment.", IRTArg::NONE,
1234 getAlignment));
1235 }
1236 if (Config.has(PassValueTypeId)) {
1237 IRTArgs.push_back(IRTArg(IIRB.Int32Ty, "value_type_id",
1238 "The type id of the stored value.", IRTArg::TYPEID,
1240 }
1241 if (Config.has(PassValueSubTypeId)) {
1242 IRTArgs.push_back(IRTArg(
1243 IIRB.Int32Ty, "value_sub_type_id",
1244 "The type id of the stored value (for arrays and vectors, or -1).",
1246 }
1247 if (Config.has(PassAtomicityOrdering)) {
1248 IRTArgs.push_back(IRTArg(IIRB.Int32Ty, "atomicity_ordering",
1249 "The atomicity ordering of the store.",
1251 }
1252 if (Config.has(PassSyncScopeId)) {
1253 IRTArgs.push_back(IRTArg(IIRB.Int8Ty, "sync_scope_id",
1254 "The sync scope id of the store.", IRTArg::NONE,
1256 }
1257 if (Config.has(PassIsVolatile)) {
1258 IRTArgs.push_back(IRTArg(IIRB.Int8Ty, "is_volatile",
1259 "Flag indicating a volatile store.", IRTArg::NONE,
1260 isVolatile));
1261 }
1262
1263 addCommonArgs(IConf, IIRB.Ctx, Config.has(PassId));
1264 IConf.addChoice(*this, IIRB.Ctx);
1265}
1266
1269 auto &SI = cast<StoreInst>(V);
1270 return SI.getPointerOperand();
1271}
1272
1275 auto &SI = cast<StoreInst>(V);
1276 SI.setOperand(SI.getPointerOperandIndex(), &NewV);
1277 return &SI;
1278}
1279
1282 auto &SI = cast<StoreInst>(V);
1283 return getCI(&Ty, SI.getPointerAddressSpace());
1284}
1285
1287 InstrumentationConfig &IConf,
1289 auto &SI = cast<StoreInst>(V);
1290 return IConf.getBasePointerInfo(*SI.getPointerOperand(), IIRB);
1291}
1292
1295 auto &SI = cast<StoreInst>(V);
1296 return SI.getValueOperand();
1297}
1298
1301 auto &SI = cast<StoreInst>(V);
1302 auto &DL = SI.getDataLayout();
1303 return getCI(&Ty, DL.getTypeStoreSize(SI.getValueOperand()->getType()));
1304}
1305
1308 auto &SI = cast<StoreInst>(V);
1309 return getCI(&Ty, SI.getAlign().value());
1310}
1311
1314 auto &SI = cast<StoreInst>(V);
1315 return getCI(&Ty, SI.getValueOperand()->getType()->getTypeID());
1316}
1317
1319 InstrumentationConfig &IConf,
1321 auto &SI = cast<StoreInst>(V);
1322 return getSubTypeID(*SI.getValueOperand()->getType(), Ty);
1323}
1324
1326 InstrumentationConfig &IConf,
1328 auto &SI = cast<StoreInst>(V);
1329 return getCI(&Ty, uint64_t(SI.getOrdering()));
1330}
1331
1334 auto &SI = cast<StoreInst>(V);
1335 return getCI(&Ty, uint64_t(SI.getSyncScopeID()));
1336}
1337
1340 auto &SI = cast<StoreInst>(V);
1341 return getCI(&Ty, SI.isVolatile());
1342}
1343
1345 ConfigTy *UserConfig) {
1347 if (UserConfig)
1348 Config = *UserConfig;
1349 if (Config.has(PassPointer)) {
1350 IRTArgs.push_back(
1351 IRTArg(IIRB.PtrTy, "pointer", "The accessed pointer.",
1352 ((IsPRE && Config.has(ReplacePointer)) ? IRTArg::REPLACABLE
1353 : IRTArg::NONE),
1355 }
1356 if (Config.has(PassPointerAS)) {
1357 IRTArgs.push_back(IRTArg(IIRB.Int32Ty, "pointer_as",
1358 "The address space of the accessed pointer.",
1360 }
1361 if (Config.has(PassBasePointerInfo)) {
1362 IRTArgs.push_back(IRTArg(IIRB.PtrTy, "base_pointer_info",
1363 "The runtime provided base pointer info.",
1365 }
1366 if (!IsPRE && Config.has(PassValue)) {
1367 IRTArgs.push_back(
1368 IRTArg(getValueType(IIRB), "value", "The loaded value.",
1369 Config.has(ReplaceValue)
1372 : IRTArg::NONE)
1373 : IRTArg::NONE,
1374 getValue, Config.has(ReplaceValue) ? replaceValue : nullptr));
1375 }
1376 if (Config.has(PassValueSize)) {
1377 IRTArgs.push_back(IRTArg(IIRB.Int64Ty, "value_size",
1378 "The size of the loaded value.", IRTArg::NONE,
1379 getValueSize));
1380 }
1381 if (Config.has(PassAlignment)) {
1382 IRTArgs.push_back(IRTArg(IIRB.Int64Ty, "alignment",
1383 "The known access alignment.", IRTArg::NONE,
1384 getAlignment));
1385 }
1386 if (Config.has(PassValueTypeId)) {
1387 IRTArgs.push_back(IRTArg(IIRB.Int32Ty, "value_type_id",
1388 "The type id of the loaded value.", IRTArg::TYPEID,
1390 }
1391 if (Config.has(PassValueSubTypeId)) {
1392 IRTArgs.push_back(IRTArg(
1393 IIRB.Int32Ty, "value_sub_type_id",
1394 "The sub type id of the loaded value (for arrays and vectors, or -1).",
1396 }
1397 if (Config.has(PassAtomicityOrdering)) {
1398 IRTArgs.push_back(IRTArg(IIRB.Int32Ty, "atomicity_ordering",
1399 "The atomicity ordering of the load.",
1401 }
1402 if (Config.has(PassSyncScopeId)) {
1403 IRTArgs.push_back(IRTArg(IIRB.Int8Ty, "sync_scope_id",
1404 "The sync scope id of the load.", IRTArg::NONE,
1406 }
1407 if (Config.has(PassIsVolatile)) {
1408 IRTArgs.push_back(IRTArg(IIRB.Int8Ty, "is_volatile",
1409 "Flag indicating a volatile load.", IRTArg::NONE,
1410 isVolatile));
1411 }
1412
1413 addCommonArgs(IConf, IIRB.Ctx, Config.has(PassId));
1414 IConf.addChoice(*this, IIRB.Ctx);
1415}
1416
1419 auto &LI = cast<LoadInst>(V);
1420 return LI.getPointerOperand();
1421}
1422
1425 auto &LI = cast<LoadInst>(V);
1426 LI.setOperand(LI.getPointerOperandIndex(), &NewV);
1427 return &LI;
1428}
1429
1432 auto &LI = cast<LoadInst>(V);
1433 return getCI(&Ty, LI.getPointerAddressSpace());
1434}
1435
1437 InstrumentationConfig &IConf,
1439 auto &LI = cast<LoadInst>(V);
1440 return IConf.getBasePointerInfo(*LI.getPointerOperand(), IIRB);
1441}
1442
1445 return &V;
1446}
1447
1450 auto &LI = cast<LoadInst>(V);
1451 auto &DL = LI.getDataLayout();
1452 return getCI(&Ty, DL.getTypeStoreSize(LI.getType()));
1453}
1454
1457 auto &LI = cast<LoadInst>(V);
1458 return getCI(&Ty, LI.getAlign().value());
1459}
1460
1463 auto &LI = cast<LoadInst>(V);
1464 return getCI(&Ty, LI.getType()->getTypeID());
1465}
1466
1468 InstrumentationConfig &IConf,
1470 auto &LI = cast<LoadInst>(V);
1471 return getSubTypeID(*LI.getType(), Ty);
1472}
1473
1475 InstrumentationConfig &IConf,
1477 auto &LI = cast<LoadInst>(V);
1478 return getCI(&Ty, uint64_t(LI.getOrdering()));
1479}
1480
1483 auto &LI = cast<LoadInst>(V);
1484 return getCI(&Ty, uint64_t(LI.getSyncScopeID()));
1485}
1486
1489 auto &LI = cast<LoadInst>(V);
1490 return getCI(&Ty, LI.isVolatile());
1491}
1492
1494 InstrumentorIRBuilderTy &IIRB, ConfigTy *UserConfig) {
1495 if (UserConfig)
1496 Config = *UserConfig;
1497 if (Config.has(PassPointer))
1498 IRTArgs.push_back(IRTArg(IIRB.PtrTy, "base_pointer",
1499 "The base pointer in question.",
1501 if (Config.has(PassPointerKind))
1502 IRTArgs.push_back(IRTArg(
1503 IIRB.Int32Ty, "base_pointer_kind",
1504 "The base pointer kind (argument, global, instruction, unknown).",
1506 addCommonArgs(IConf, IIRB.Ctx, Config.has(PassId));
1507 IConf.addChoice(*this, IIRB.Ctx);
1508}
1509
1511 InstrumentationConfig &IConf,
1513 if (isa<Argument>(V))
1514 return getCI(&Ty, 0);
1515 if (isa<GlobalValue>(V))
1516 return getCI(&Ty, 1);
1517 if (isa<Instruction>(V))
1518 return getCI(&Ty, 2);
1519 return getCI(&Ty, 3);
1520}
1521
1523 ConfigTy *UserConfig) {
1524 if (UserConfig)
1525 Config = *UserConfig;
1526
1527 if (Config.has(PassName))
1528 IRTArgs.push_back(IRTArg(IIRB.PtrTy, "module_name",
1529 "The module/translation unit name.",
1531 if (Config.has(PassTargetTriple))
1532 IRTArgs.push_back(IRTArg(IIRB.PtrTy, "target_triple", "The target triple.",
1534
1535 addCommonArgs(IConf, IIRB.Ctx, Config.has(PassId));
1536 IConf.addChoice(*this, IIRB.Ctx);
1537}
1540 // V is a constructor or destructor of the module we can place code in.
1541 auto &Fn = cast<Function>(V);
1542 return IConf.getGlobalString(Fn.getParent()->getName(), IIRB);
1543}
1545 InstrumentationConfig &IConf,
1547 // V is a constructor or destructor of the module we can place code in.
1548 auto &Fn = cast<Function>(V);
1549 return IConf.getGlobalString(Fn.getParent()->getTargetTriple().getTriple(),
1550 IIRB);
1551}
1552
1554 InstrumentorIRBuilderTy &IIRB, ConfigTy *UserConfig) {
1555 if (UserConfig)
1556 Config = *UserConfig;
1558 if (Config.has(PassAddress))
1559 IRTArgs.push_back(IRTArg(
1560 IIRB.PtrTy, "address",
1561 "The address of the global (replaceable for definitions).",
1564 if (Config.has(PassAS))
1565 IRTArgs.push_back(IRTArg(IIRB.Int32Ty, "address_space",
1566 "The address space of the global.", IRTArg::NONE,
1567 getAS));
1568 if (Config.has(PassDeclaredSize))
1569 IRTArgs.push_back(IRTArg(IIRB.Int64Ty, "declared_size",
1570 "The size of the declared type of the global.",
1572 if (Config.has(PassAlignment))
1573 IRTArgs.push_back(IRTArg(IIRB.Int64Ty, "alignment",
1574 "The allocation alignment.", IRTArg::NONE,
1575 getAlignment));
1576 if (Config.has(PassName))
1577 IRTArgs.push_back(IRTArg(IIRB.PtrTy, "name", "The name of the global.",
1579 if (Config.has(PassInitialValue))
1580 IRTArgs.push_back(IRTArg(
1581 IIRB.Int64Ty, "initial_value", "The initial value of the global.",
1584 if (Config.has(PassIsConstant))
1585 IRTArgs.push_back(IRTArg(IIRB.Int8Ty, "is_constant",
1586 "Flag to indicate constant globals.", IRTArg::NONE,
1587 isConstant));
1588 if (Config.has(PassIsDefinition))
1589 IRTArgs.push_back(IRTArg(IIRB.Int8Ty, "is_definition",
1590 "Flag to indicate global definitions.",
1592 addCommonArgs(IConf, IIRB.Ctx, Config.has(PassId));
1593 IConf.addChoice(*this, IIRB.Ctx);
1594}
1598 if (GV.getAddressSpace())
1599 return ConstantExpr::getAddrSpaceCast(&GV, IIRB.PtrTy);
1600 return &GV;
1601}
1603 InstrumentationConfig &IConf,
1606
1607 GlobalVariable *ShadowGV = nullptr;
1608 auto ShadowName = IConf.getRTName("shadow.", GV.getName());
1609 auto &DL = GV.getDataLayout();
1610 if (GV.isDeclaration()) {
1611 ShadowGV = new GlobalVariable(*GV.getParent(), GV.getType(), false,
1613 ShadowName, &GV, GV.getThreadLocalMode(),
1614 DL.getDefaultGlobalsAddressSpace());
1615 } else {
1616 ShadowGV = new GlobalVariable(
1617 *GV.getParent(), NewV.getType(), false, GV.getLinkage(),
1618 PoisonValue::get(NewV.getType()), ShadowName, &GV);
1619 IIRB.IRB.CreateStore(&NewV, ShadowGV);
1620 }
1621
1625 DenseMap<Value *, Instruction *> ConstToInstMap;
1627
1628 auto MakeInstForConst = [&](Use &U) {
1629 Instruction *&I = ConstToInstMap[U];
1630 if (I)
1631 return;
1632 if (U == &GV) {
1633 } else if (auto *CE = dyn_cast<ConstantExpr>(U)) {
1634 I = CE->getAsInstruction();
1635 }
1636 };
1637
1638 auto InsertConsts = [&](Instruction *UserI, Use &UserU) {
1640 auto *&Reload = ReloadMap[UserI->getFunction()];
1641 if (!Reload) {
1642 Reload = new LoadInst(
1643 GV.getType(), ShadowGV, GV.getName() + ".shadow_load",
1645 IIRB.NewInsts.insert({Reload, IIRB.Epoch});
1646 }
1647 Worklist.push_back({UserI, &UserU});
1648 while (!Worklist.empty()) {
1649 auto [I, U] = Worklist.pop_back_val();
1650 if (*U == &GV) {
1651 U->set(ReloadMap[I->getFunction()]);
1652 continue;
1653 }
1654 if (auto *CI = ConstToInstMap[*U]) {
1655 auto *CIClone = CI->clone();
1656 IIRB.NewInsts.insert({CIClone, IIRB.Epoch});
1657 if (auto *PHI = dyn_cast<PHINode>(I)) {
1658 auto *BB = PHI->getIncomingBlock(U->getOperandNo());
1659 CIClone->insertBefore(BB->getTerminator()->getIterator());
1660 } else {
1661 CIClone->insertBefore(I->getIterator());
1662 }
1663 U->set(CIClone);
1664 for (auto &CICUse : CIClone->operands()) {
1665 Worklist.push_back({CIClone, &CICUse});
1666 }
1667 }
1668 }
1669 };
1670
1671 SmallPtrSet<Use *, 8> Visited;
1672 while (!Worklist.empty()) {
1673 Use *U = Worklist.pop_back_val();
1674 if (!Done.insert(U).second)
1675 continue;
1676 MakeInstForConst(*U);
1677 auto *I = dyn_cast<Instruction>(U->getUser());
1678 if (!I) {
1679 append_range(Worklist, make_pointer_range(U->getUser()->uses()));
1680 continue;
1681 }
1682 if (IIRB.NewInsts.lookup(I) == IIRB.Epoch)
1683 continue;
1685 continue;
1686 if (auto *II = dyn_cast<IntrinsicInst>(I))
1687 if (II->getIntrinsicID() == Intrinsic::eh_typeid_for)
1688 continue;
1689 if (I->getParent())
1690 InsertConsts(I, *U);
1691 }
1692
1693 for (auto &It : ConstToInstMap)
1694 if (It.second)
1695 It.second->deleteValue();
1696
1697 return &V;
1698}
1702 return getCI(&Ty, GV.getAddressSpace());
1703}
1705 InstrumentationConfig &IConf,
1708 MaybeAlign Alignment = GV.getAlign();
1709 return getCI(&Ty, Alignment ? Alignment->value() : 0);
1710}
1712 InstrumentationConfig &IConf,
1715 auto &DL = GV.getDataLayout();
1716 return getCI(&Ty, DL.getTypeAllocSize(GV.getValueType()));
1717}
1719 InstrumentationConfig &IConf,
1722 return IConf.getGlobalString(GV.getName(), IIRB);
1723}
1734 return getCI(&Ty, GV.isConstant());
1735}
1737 InstrumentationConfig &IConf,
1740 return getCI(&Ty, !GV.isDeclaration());
1741}
1742
1743/// CastIO
1744/// {
1746 ConfigTy *UserConfig) {
1747 if (UserConfig)
1748 Config = *UserConfig;
1750 if (Config.has(PassInput))
1751 IRTArgs.push_back(
1752 IRTArg(IIRB.Int64Ty, "input", "Input value of the cast.",
1755 : IRTArg::NONE),
1756 getInput));
1757 if (Config.has(PassInputTypeId))
1758 IRTArgs.push_back(IRTArg(IIRB.Int32Ty, "input_type_id",
1759 "The type id of the input value.", IRTArg::TYPEID,
1761 if (Config.has(PassInputSubTypeId))
1762 IRTArgs.push_back(IRTArg(
1763 IIRB.Int32Ty, "input_sub_type_id",
1764 "The sub type id of the input value (for arrays and vectors, or -1).",
1766 if (Config.has(PassInputSize))
1767 IRTArgs.push_back(IRTArg(IIRB.Int32Ty, "input_size",
1768 "The size of the input value.", IRTArg::NONE,
1769 getInputSize));
1770 if (!IsPRE && Config.has(PassResult))
1771 IRTArgs.push_back(
1772 IRTArg(IIRB.Int64Ty, "result", "Result of the cast.",
1775 : IRTArg::NONE),
1776 getValue, Config.has(ReplaceResult) ? replaceValue : nullptr));
1777 if (Config.has(PassResultTypeId))
1778 IRTArgs.push_back(IRTArg(IIRB.Int32Ty, "result_type_id",
1779 "The type id of the result value.", IRTArg::TYPEID,
1781 if (Config.has(PassResultSubTypeId))
1782 IRTArgs.push_back(IRTArg(
1783 IIRB.Int32Ty, "result_sub_type_id",
1784 "The sub type id of the result value (for arrays and vectors, or -1).",
1786 if (Config.has(PassResultSize))
1787 IRTArgs.push_back(IRTArg(IIRB.Int32Ty, "result_size",
1788 "The size of the result value.", IRTArg::NONE,
1789 getResultSize));
1790 if (Config.has(PassOpcode))
1791 IRTArgs.push_back(IRTArg(IIRB.Int32Ty, "opcode",
1792 "The opcode of the cast instruction.",
1794
1795 addCommonArgs(IConf, IIRB.Ctx, Config.has(PassId));
1796 IConf.addChoice(*this, IIRB.Ctx);
1797}
1798
1801 auto &CI = cast<CastInst>(V);
1802 return CI.getOperand(0);
1803}
1804
1807 auto &CI = cast<CastInst>(V);
1808 return getCI(&Ty, CI.getSrcTy()->getTypeID());
1809}
1810
1812 InstrumentationConfig &IConf,
1814 auto &CI = cast<CastInst>(V);
1815 return getSubTypeID(*CI.getSrcTy(), Ty);
1816}
1817
1820 auto &CI = cast<CastInst>(V);
1821 auto &DL = CI.getDataLayout();
1822 return getCI(&Ty, DL.getTypeStoreSize(CI.getSrcTy()));
1823}
1824
1827 auto &CI = cast<CastInst>(V);
1828 return getCI(&Ty, CI.getDestTy()->getTypeID());
1829}
1830
1832 InstrumentationConfig &IConf,
1834 auto &CI = cast<CastInst>(V);
1835 return getSubTypeID(*CI.getDestTy(), Ty);
1836}
1837
1840 auto &CI = cast<CastInst>(V);
1841 auto &DL = CI.getDataLayout();
1842 return getCI(&Ty, DL.getTypeStoreSize(CI.getDestTy()));
1843}
1844///}
1845
1848 auto &I = cast<Instruction>(V);
1849 uint64_t Flag = NUMERIC_FLAG_NONE;
1850
1851 switch (I.getOpcode()) {
1852 case Instruction::Add:
1853 case Instruction::Sub:
1854 case Instruction::Mul:
1855 case Instruction::Shl:
1856 if (I.hasNoSignedWrap())
1858 if (I.hasNoUnsignedWrap())
1860 break;
1861 case Instruction::FAdd:
1862 case Instruction::FSub:
1863 case Instruction::FMul:
1864 case Instruction::FDiv:
1865 case Instruction::FNeg:
1866 if (I.hasNoNaNs())
1868 if (I.hasNoInfs())
1870 if (I.hasNoSignedZeros())
1872 break;
1873 case Instruction::AShr:
1874 case Instruction::LShr:
1875 case Instruction::SDiv:
1876 case Instruction::UDiv:
1877 if (I.isExact())
1878 Flag |= NUMERIC_FLAG_IS_EXACT;
1879 break;
1880 }
1881
1882 if (auto *DI = dyn_cast<PossiblyDisjointInst>(&V))
1883 if (DI->isDisjoint())
1885
1886 return getCI(&Ty, Flag);
1887}
1888
1897
1899 InstrumentorIRBuilderTy &IIRB, ConfigTy *UserConfig) {
1900 if (UserConfig)
1901 Config = UserConfig;
1903 const auto ValArgOpts =
1906 if (Config.has(PassTypeId))
1907 IRTArgs.push_back(IRTArg(IIRB.Int32Ty, "type_id",
1908 "The operation's type id.", IRTArg::TYPEID,
1909 getTypeId));
1910 if (Config.has(PassSubTypeId))
1911 IRTArgs.push_back(
1912 IRTArg(IIRB.Int32Ty, "sub_type_id",
1913 "The operation's sub type id (for arrays and vectors, or -1).",
1915 if (Config.has(PassSize))
1916 IRTArgs.push_back(IRTArg(IIRB.Int32Ty, "size", "The operation's type size.",
1918 if (Config.has(PassOpcode))
1919 IRTArgs.push_back(IRTArg(IIRB.Int32Ty, "opcode", "The instruction opcode.",
1921 if (Config.has(PassLeft))
1922 IRTArgs.push_back(IRTArg(IIRB.Int64Ty, "left",
1923 "The operation's left operand.", ValArgOpts,
1925 if (Config.has(PassRight))
1926 IRTArgs.push_back(IRTArg(IIRB.Int64Ty, "right",
1927 "The operation's right operand. This value is "
1928 "poison for unary operations.",
1929 ValArgOpts, getRightOperand));
1930 if (!IsPRE && Config.has(PassResult))
1931 IRTArgs.push_back(
1932 IRTArg(IIRB.Int64Ty, "result", "Result of the operation.",
1933 IRTArg::REPLACABLE | ValArgOpts, getValue,
1934 Config.has(ReplaceResult) ? replaceValue : nullptr));
1935 if (Config.has(PassFlags))
1936 IRTArgs.push_back(
1937 IRTArg(IIRB.Int64Ty, "flags",
1938 "A bitmask value signaling which instruction flags are present.",
1940 addCommonArgs(IConf, IIRB.Ctx, Config.has(PassId));
1941 addFlagNames();
1942 IConf.addChoice(*this, IIRB.Ctx);
1943}
1944
1946 InstrumentationConfig &IConf,
1948 auto &I = cast<Instruction>(V);
1949 return getCI(&Ty, I.getOperand(0)->getType()->getTypeID());
1950}
1951
1953 InstrumentationConfig &IConf,
1955 auto &I = cast<Instruction>(V);
1956 auto &DL = I.getDataLayout();
1957 return getCI(&Ty, DL.getTypeStoreSize(I.getOperand(0)->getType()));
1958}
1959
1962 auto *CI = dyn_cast<CmpInst>(&V);
1963 return getCI(&Ty, CI->getPredicate());
1964}
1965
1972
1975 auto &I = cast<Instruction>(V);
1976 uint64_t Flag = NUMERIC_FLAG_NONE;
1977
1978 switch (I.getOpcode()) {
1979 case Instruction::ICmp:
1980 if (dyn_cast<ICmpInst>(&V)->hasSameSign())
1981 Flag |= COMPARE_FLAG_SAMESIGN;
1982 break;
1983 case Instruction::FCmp:
1984 if (I.hasNoNaNs())
1986 if (I.hasNoInfs())
1988 if (I.hasNoSignedZeros())
1990 break;
1991 }
1992
1993 return getCI(&Ty, Flag);
1994}
1995
1997 InstrumentorIRBuilderTy &IIRB, ConfigTy *UserConfig) {
1998 if (UserConfig)
1999 Config = UserConfig;
2001 const auto OperandArgOpts =
2004 if (Config.has(PassOpTypeId))
2005 IRTArgs.push_back(IRTArg(IIRB.Int32Ty, "operand_type_id",
2006 "The operand type id.", IRTArg::NONE,
2008 if (Config.has(PassOpSize))
2009 IRTArgs.push_back(IRTArg(IIRB.Int32Ty, "operand_size",
2010 "The operand type size.", IRTArg::NONE,
2012 if (Config.has(PassOpcode))
2013 IRTArgs.push_back(IRTArg(IIRB.Int32Ty, "opcode", "The instruction opcode.",
2015 if (Config.has(PassPredicate))
2016 IRTArgs.push_back(IRTArg(IIRB.Int32Ty, "predicate",
2017 "The comparison predicate ID.", IRTArg::NONE,
2018 getPredicate));
2019 if (Config.has(PassLeft))
2020 IRTArgs.push_back(IRTArg(IIRB.Int64Ty, "left",
2021 "The comparison's left operand.", OperandArgOpts,
2023 if (Config.has(PassRight))
2024 IRTArgs.push_back(IRTArg(IIRB.Int64Ty, "right",
2025 "The comparison's right operand.", OperandArgOpts,
2027 if (!IsPRE && Config.has(PassResultSize))
2028 IRTArgs.push_back(IRTArg(IIRB.Int32Ty, "result_type_id",
2029 "The result value's type ID.", IRTArg::NONE,
2030 getTypeId));
2031 if (!IsPRE && Config.has(PassResultSize))
2032 IRTArgs.push_back(IRTArg(IIRB.Int32Ty, "result_size",
2033 "Size of the result value.", IRTArg::NONE,
2034 getTypeSize));
2035 if (!IsPRE && Config.has(PassResult))
2036 IRTArgs.push_back(
2037 IRTArg(IIRB.Int64Ty, "result", "Result of the operation.",
2040 : IRTArg::NONE),
2041 getValue, Config.has(ReplaceResult) ? replaceValue : nullptr));
2042 if (Config.has(PassFlags))
2043 IRTArgs.push_back(
2044 IRTArg(IIRB.Int64Ty, "flags",
2045 "A bitmask value signaling which instruction flags are present.",
2047 addFlagNames();
2048 addCommonArgs(IConf, IIRB.Ctx, Config.has(PassId));
2049 IConf.addChoice(*this, IIRB.Ctx);
2050}
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:730
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