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 const DataLayout &DL = AI.getDataLayout();
1175 Value *SizeValue = nullptr;
1176 TypeSize TypeSize = AI.getAllocationBaseSize(DL);
1177 if (TypeSize.isFixed()) {
1178 SizeValue = getCI(&Ty, TypeSize.getFixedValue());
1179 } else {
1180 auto *NullPtr = ConstantPointerNull::get(AI.getType());
1181 SizeValue = IIRB.IRB.CreatePtrToInt(
1182 IIRB.IRB.CreateGEP(AI.getAllocatedType(), NullPtr,
1183 {IIRB.IRB.getInt32(1)}),
1184 &Ty);
1185 }
1186 if (AI.isArrayAllocation())
1187 SizeValue = IIRB.IRB.CreateMul(
1188 SizeValue, IIRB.IRB.CreateZExtOrBitCast(AI.getArraySize(), &Ty));
1189 return SizeValue;
1190}
1191
1194 auto &AI = cast<AllocaInst>(V);
1195 const DataLayout &DL = AI.getDataLayout();
1196 auto *NewAI = IIRB.IRB.CreateAlloca(IIRB.IRB.getInt8Ty(),
1197 DL.getAllocaAddrSpace(), &NewV);
1198 NewAI->setAlignment(AI.getAlign());
1199 AI.replaceAllUsesWith(NewAI);
1200 IIRB.eraseLater(&AI);
1201 return NewAI;
1202}
1203
1206 return getCI(&Ty, cast<AllocaInst>(V).getAlign().value());
1207}
1208///}
1209
1211 ConfigTy *UserConfig) {
1212 if (UserConfig)
1213 Config = *UserConfig;
1214
1216 if (Config.has(PassPointer)) {
1217 IRTArgs.push_back(
1218 IRTArg(IIRB.PtrTy, "pointer", "The accessed pointer.",
1219 ((IsPRE && Config.has(ReplacePointer)) ? IRTArg::REPLACABLE
1220 : IRTArg::NONE),
1222 }
1223 if (Config.has(PassPointerAS)) {
1224 IRTArgs.push_back(IRTArg(IIRB.Int32Ty, "pointer_as",
1225 "The address space of the accessed pointer.",
1227 }
1228 if (Config.has(PassBasePointerInfo)) {
1229 IRTArgs.push_back(IRTArg(IIRB.PtrTy, "base_pointer_info",
1230 "The runtime provided base pointer info.",
1232 }
1233 if (Config.has(PassStoredValue)) {
1234 IRTArgs.push_back(
1235 IRTArg(getValueType(IIRB), "value", "The stored value.",
1238 : IRTArg::NONE),
1239 getValue));
1240 }
1241 if (Config.has(PassStoredValueSize)) {
1242 IRTArgs.push_back(IRTArg(IIRB.Int64Ty, "value_size",
1243 "The size of the stored value.", IRTArg::NONE,
1244 getValueSize));
1245 }
1246 if (Config.has(PassAlignment)) {
1247 IRTArgs.push_back(IRTArg(IIRB.Int64Ty, "alignment",
1248 "The known access alignment.", IRTArg::NONE,
1249 getAlignment));
1250 }
1251 if (Config.has(PassValueTypeId)) {
1252 IRTArgs.push_back(IRTArg(IIRB.Int32Ty, "value_type_id",
1253 "The type id of the stored value.", IRTArg::TYPEID,
1255 }
1256 if (Config.has(PassValueSubTypeId)) {
1257 IRTArgs.push_back(IRTArg(
1258 IIRB.Int32Ty, "value_sub_type_id",
1259 "The type id of the stored value (for arrays and vectors, or -1).",
1261 }
1262 if (Config.has(PassAtomicityOrdering)) {
1263 IRTArgs.push_back(IRTArg(IIRB.Int32Ty, "atomicity_ordering",
1264 "The atomicity ordering of the store.",
1266 }
1267 if (Config.has(PassSyncScopeId)) {
1268 IRTArgs.push_back(IRTArg(IIRB.Int8Ty, "sync_scope_id",
1269 "The sync scope id of the store.", IRTArg::NONE,
1271 }
1272 if (Config.has(PassIsVolatile)) {
1273 IRTArgs.push_back(IRTArg(IIRB.Int8Ty, "is_volatile",
1274 "Flag indicating a volatile store.", IRTArg::NONE,
1275 isVolatile));
1276 }
1277
1278 addCommonArgs(IConf, IIRB.Ctx, Config.has(PassId));
1279 IConf.addChoice(*this, IIRB.Ctx);
1280}
1281
1284 auto &SI = cast<StoreInst>(V);
1285 return SI.getPointerOperand();
1286}
1287
1290 auto &SI = cast<StoreInst>(V);
1291 SI.setOperand(SI.getPointerOperandIndex(), &NewV);
1292 return &SI;
1293}
1294
1297 auto &SI = cast<StoreInst>(V);
1298 return getCI(&Ty, SI.getPointerAddressSpace());
1299}
1300
1302 InstrumentationConfig &IConf,
1304 auto &SI = cast<StoreInst>(V);
1305 return IConf.getBasePointerInfo(*SI.getPointerOperand(), IIRB);
1306}
1307
1310 auto &SI = cast<StoreInst>(V);
1311 return SI.getValueOperand();
1312}
1313
1316 auto &SI = cast<StoreInst>(V);
1317 auto &DL = SI.getDataLayout();
1318 return getCI(&Ty, DL.getTypeStoreSize(SI.getValueOperand()->getType()));
1319}
1320
1323 auto &SI = cast<StoreInst>(V);
1324 return getCI(&Ty, SI.getAlign().value());
1325}
1326
1329 auto &SI = cast<StoreInst>(V);
1330 return getCI(&Ty, SI.getValueOperand()->getType()->getTypeID());
1331}
1332
1334 InstrumentationConfig &IConf,
1336 auto &SI = cast<StoreInst>(V);
1337 return getSubTypeID(*SI.getValueOperand()->getType(), Ty);
1338}
1339
1341 InstrumentationConfig &IConf,
1343 auto &SI = cast<StoreInst>(V);
1344 return getCI(&Ty, uint64_t(SI.getOrdering()));
1345}
1346
1349 auto &SI = cast<StoreInst>(V);
1350 return getCI(&Ty, uint64_t(SI.getSyncScopeID()));
1351}
1352
1355 auto &SI = cast<StoreInst>(V);
1356 return getCI(&Ty, SI.isVolatile());
1357}
1358
1360 ConfigTy *UserConfig) {
1362 if (UserConfig)
1363 Config = *UserConfig;
1364 if (Config.has(PassPointer)) {
1365 IRTArgs.push_back(
1366 IRTArg(IIRB.PtrTy, "pointer", "The accessed pointer.",
1367 ((IsPRE && Config.has(ReplacePointer)) ? IRTArg::REPLACABLE
1368 : IRTArg::NONE),
1370 }
1371 if (Config.has(PassPointerAS)) {
1372 IRTArgs.push_back(IRTArg(IIRB.Int32Ty, "pointer_as",
1373 "The address space of the accessed pointer.",
1375 }
1376 if (Config.has(PassBasePointerInfo)) {
1377 IRTArgs.push_back(IRTArg(IIRB.PtrTy, "base_pointer_info",
1378 "The runtime provided base pointer info.",
1380 }
1381 if (!IsPRE && Config.has(PassValue)) {
1382 IRTArgs.push_back(
1383 IRTArg(getValueType(IIRB), "value", "The loaded value.",
1384 Config.has(ReplaceValue)
1387 : IRTArg::NONE)
1388 : IRTArg::NONE,
1389 getValue, Config.has(ReplaceValue) ? replaceValue : nullptr));
1390 }
1391 if (Config.has(PassValueSize)) {
1392 IRTArgs.push_back(IRTArg(IIRB.Int64Ty, "value_size",
1393 "The size of the loaded value.", IRTArg::NONE,
1394 getValueSize));
1395 }
1396 if (Config.has(PassAlignment)) {
1397 IRTArgs.push_back(IRTArg(IIRB.Int64Ty, "alignment",
1398 "The known access alignment.", IRTArg::NONE,
1399 getAlignment));
1400 }
1401 if (Config.has(PassValueTypeId)) {
1402 IRTArgs.push_back(IRTArg(IIRB.Int32Ty, "value_type_id",
1403 "The type id of the loaded value.", IRTArg::TYPEID,
1405 }
1406 if (Config.has(PassValueSubTypeId)) {
1407 IRTArgs.push_back(IRTArg(
1408 IIRB.Int32Ty, "value_sub_type_id",
1409 "The sub type id of the loaded value (for arrays and vectors, or -1).",
1411 }
1412 if (Config.has(PassAtomicityOrdering)) {
1413 IRTArgs.push_back(IRTArg(IIRB.Int32Ty, "atomicity_ordering",
1414 "The atomicity ordering of the load.",
1416 }
1417 if (Config.has(PassSyncScopeId)) {
1418 IRTArgs.push_back(IRTArg(IIRB.Int8Ty, "sync_scope_id",
1419 "The sync scope id of the load.", IRTArg::NONE,
1421 }
1422 if (Config.has(PassIsVolatile)) {
1423 IRTArgs.push_back(IRTArg(IIRB.Int8Ty, "is_volatile",
1424 "Flag indicating a volatile load.", IRTArg::NONE,
1425 isVolatile));
1426 }
1427
1428 addCommonArgs(IConf, IIRB.Ctx, Config.has(PassId));
1429 IConf.addChoice(*this, IIRB.Ctx);
1430}
1431
1434 auto &LI = cast<LoadInst>(V);
1435 return LI.getPointerOperand();
1436}
1437
1440 auto &LI = cast<LoadInst>(V);
1441 LI.setOperand(LI.getPointerOperandIndex(), &NewV);
1442 return &LI;
1443}
1444
1447 auto &LI = cast<LoadInst>(V);
1448 return getCI(&Ty, LI.getPointerAddressSpace());
1449}
1450
1452 InstrumentationConfig &IConf,
1454 auto &LI = cast<LoadInst>(V);
1455 return IConf.getBasePointerInfo(*LI.getPointerOperand(), IIRB);
1456}
1457
1460 return &V;
1461}
1462
1465 auto &LI = cast<LoadInst>(V);
1466 auto &DL = LI.getDataLayout();
1467 return getCI(&Ty, DL.getTypeStoreSize(LI.getType()));
1468}
1469
1472 auto &LI = cast<LoadInst>(V);
1473 return getCI(&Ty, LI.getAlign().value());
1474}
1475
1478 auto &LI = cast<LoadInst>(V);
1479 return getCI(&Ty, LI.getType()->getTypeID());
1480}
1481
1483 InstrumentationConfig &IConf,
1485 auto &LI = cast<LoadInst>(V);
1486 return getSubTypeID(*LI.getType(), Ty);
1487}
1488
1490 InstrumentationConfig &IConf,
1492 auto &LI = cast<LoadInst>(V);
1493 return getCI(&Ty, uint64_t(LI.getOrdering()));
1494}
1495
1498 auto &LI = cast<LoadInst>(V);
1499 return getCI(&Ty, uint64_t(LI.getSyncScopeID()));
1500}
1501
1504 auto &LI = cast<LoadInst>(V);
1505 return getCI(&Ty, LI.isVolatile());
1506}
1507
1509 InstrumentorIRBuilderTy &IIRB, ConfigTy *UserConfig) {
1510 if (UserConfig)
1511 Config = *UserConfig;
1512 if (Config.has(PassPointer))
1513 IRTArgs.push_back(IRTArg(IIRB.PtrTy, "base_pointer",
1514 "The base pointer in question.",
1516 if (Config.has(PassPointerKind))
1517 IRTArgs.push_back(IRTArg(
1518 IIRB.Int32Ty, "base_pointer_kind",
1519 "The base pointer kind (argument, global, instruction, unknown).",
1521 addCommonArgs(IConf, IIRB.Ctx, Config.has(PassId));
1522 IConf.addChoice(*this, IIRB.Ctx);
1523}
1524
1526 InstrumentationConfig &IConf,
1528 if (isa<Argument>(V))
1529 return getCI(&Ty, 0);
1530 if (isa<GlobalValue>(V))
1531 return getCI(&Ty, 1);
1532 if (isa<Instruction>(V))
1533 return getCI(&Ty, 2);
1534 return getCI(&Ty, 3);
1535}
1536
1538 ConfigTy *UserConfig) {
1539 if (UserConfig)
1540 Config = *UserConfig;
1541
1542 if (Config.has(PassName))
1543 IRTArgs.push_back(IRTArg(IIRB.PtrTy, "module_name",
1544 "The module/translation unit name.",
1546 if (Config.has(PassTargetTriple))
1547 IRTArgs.push_back(IRTArg(IIRB.PtrTy, "target_triple", "The target triple.",
1549
1550 addCommonArgs(IConf, IIRB.Ctx, Config.has(PassId));
1551 IConf.addChoice(*this, IIRB.Ctx);
1552}
1555 // V is a constructor or destructor of the module we can place code in.
1556 auto &Fn = cast<Function>(V);
1557 return IConf.getGlobalString(Fn.getParent()->getName(), IIRB);
1558}
1560 InstrumentationConfig &IConf,
1562 // V is a constructor or destructor of the module we can place code in.
1563 auto &Fn = cast<Function>(V);
1564 return IConf.getGlobalString(Fn.getParent()->getTargetTriple().getTriple(),
1565 IIRB);
1566}
1567
1569 InstrumentorIRBuilderTy &IIRB, ConfigTy *UserConfig) {
1570 if (UserConfig)
1571 Config = *UserConfig;
1573 if (Config.has(PassAddress))
1574 IRTArgs.push_back(IRTArg(
1575 IIRB.PtrTy, "address",
1576 "The address of the global (replaceable for definitions).",
1579 if (Config.has(PassAS))
1580 IRTArgs.push_back(IRTArg(IIRB.Int32Ty, "address_space",
1581 "The address space of the global.", IRTArg::NONE,
1582 getAS));
1583 if (Config.has(PassDeclaredSize))
1584 IRTArgs.push_back(IRTArg(IIRB.Int64Ty, "declared_size",
1585 "The size of the declared type of the global.",
1587 if (Config.has(PassAlignment))
1588 IRTArgs.push_back(IRTArg(IIRB.Int64Ty, "alignment",
1589 "The allocation alignment.", IRTArg::NONE,
1590 getAlignment));
1591 if (Config.has(PassName))
1592 IRTArgs.push_back(IRTArg(IIRB.PtrTy, "name", "The name of the global.",
1594 if (Config.has(PassInitialValue))
1595 IRTArgs.push_back(IRTArg(
1596 IIRB.Int64Ty, "initial_value", "The initial value of the global.",
1599 if (Config.has(PassIsConstant))
1600 IRTArgs.push_back(IRTArg(IIRB.Int8Ty, "is_constant",
1601 "Flag to indicate constant globals.", IRTArg::NONE,
1602 isConstant));
1603 if (Config.has(PassIsDefinition))
1604 IRTArgs.push_back(IRTArg(IIRB.Int8Ty, "is_definition",
1605 "Flag to indicate global definitions.",
1607 addCommonArgs(IConf, IIRB.Ctx, Config.has(PassId));
1608 IConf.addChoice(*this, IIRB.Ctx);
1609}
1613 if (GV.getAddressSpace())
1614 return ConstantExpr::getAddrSpaceCast(&GV, IIRB.PtrTy);
1615 return &GV;
1616}
1618 InstrumentationConfig &IConf,
1621
1622 GlobalVariable *ShadowGV = nullptr;
1623 auto ShadowName = IConf.getRTName("shadow.", GV.getName());
1624 auto &DL = GV.getDataLayout();
1625 if (GV.isDeclaration()) {
1626 ShadowGV = new GlobalVariable(*GV.getParent(), GV.getType(), false,
1628 ShadowName, &GV, GV.getThreadLocalMode(),
1629 DL.getDefaultGlobalsAddressSpace());
1630 } else {
1631 ShadowGV = new GlobalVariable(
1632 *GV.getParent(), NewV.getType(), false, GV.getLinkage(),
1633 PoisonValue::get(NewV.getType()), ShadowName, &GV);
1634 IIRB.IRB.CreateStore(&NewV, ShadowGV);
1635 }
1636
1640 DenseMap<Value *, Instruction *> ConstToInstMap;
1642
1643 auto MakeInstForConst = [&](Use &U) {
1644 Instruction *&I = ConstToInstMap[U];
1645 if (I)
1646 return;
1647 if (U == &GV) {
1648 } else if (auto *CE = dyn_cast<ConstantExpr>(U)) {
1649 I = CE->getAsInstruction();
1650 }
1651 };
1652
1653 auto InsertConsts = [&](Instruction *UserI, Use &UserU) {
1655 auto *&Reload = ReloadMap[UserI->getFunction()];
1656 if (!Reload) {
1657 Reload = new LoadInst(
1658 GV.getType(), ShadowGV, GV.getName() + ".shadow_load",
1660 IIRB.NewInsts.insert({Reload, IIRB.Epoch});
1661 }
1662 Worklist.push_back({UserI, &UserU});
1663 while (!Worklist.empty()) {
1664 auto [I, U] = Worklist.pop_back_val();
1665 if (*U == &GV) {
1666 U->set(ReloadMap[I->getFunction()]);
1667 continue;
1668 }
1669 if (auto *CI = ConstToInstMap[*U]) {
1670 auto *CIClone = CI->clone();
1671 IIRB.NewInsts.insert({CIClone, IIRB.Epoch});
1672 if (auto *PHI = dyn_cast<PHINode>(I)) {
1673 auto *BB = PHI->getIncomingBlock(U->getOperandNo());
1674 CIClone->insertBefore(BB->getTerminator()->getIterator());
1675 } else {
1676 CIClone->insertBefore(I->getIterator());
1677 }
1678 U->set(CIClone);
1679 for (auto &CICUse : CIClone->operands()) {
1680 Worklist.push_back({CIClone, &CICUse});
1681 }
1682 }
1683 }
1684 };
1685
1686 SmallPtrSet<Use *, 8> Visited;
1687 while (!Worklist.empty()) {
1688 Use *U = Worklist.pop_back_val();
1689 if (!Done.insert(U).second)
1690 continue;
1691 MakeInstForConst(*U);
1692 auto *I = dyn_cast<Instruction>(U->getUser());
1693 if (!I) {
1694 append_range(Worklist, make_pointer_range(U->getUser()->uses()));
1695 continue;
1696 }
1697 if (IIRB.NewInsts.lookup(I) == IIRB.Epoch)
1698 continue;
1700 continue;
1701 if (auto *II = dyn_cast<IntrinsicInst>(I))
1702 if (II->getIntrinsicID() == Intrinsic::eh_typeid_for)
1703 continue;
1704 if (I->getParent())
1705 InsertConsts(I, *U);
1706 }
1707
1708 for (auto &It : ConstToInstMap)
1709 if (It.second)
1710 It.second->deleteValue();
1711
1712 return &V;
1713}
1717 return getCI(&Ty, GV.getAddressSpace());
1718}
1720 InstrumentationConfig &IConf,
1723 MaybeAlign Alignment = GV.getAlign();
1724 return getCI(&Ty, Alignment ? Alignment->value() : 0);
1725}
1727 InstrumentationConfig &IConf,
1730 auto &DL = GV.getDataLayout();
1731 return getCI(&Ty, DL.getTypeAllocSize(GV.getValueType()));
1732}
1734 InstrumentationConfig &IConf,
1737 return IConf.getGlobalString(GV.getName(), IIRB);
1738}
1749 return getCI(&Ty, GV.isConstant());
1750}
1752 InstrumentationConfig &IConf,
1755 return getCI(&Ty, !GV.isDeclaration());
1756}
1757
1758/// CastIO
1759/// {
1761 ConfigTy *UserConfig) {
1762 if (UserConfig)
1763 Config = *UserConfig;
1765 if (Config.has(PassInput))
1766 IRTArgs.push_back(
1767 IRTArg(IIRB.Int64Ty, "input", "Input value of the cast.",
1770 : IRTArg::NONE),
1771 getInput));
1772 if (Config.has(PassInputTypeId))
1773 IRTArgs.push_back(IRTArg(IIRB.Int32Ty, "input_type_id",
1774 "The type id of the input value.", IRTArg::TYPEID,
1776 if (Config.has(PassInputSubTypeId))
1777 IRTArgs.push_back(IRTArg(
1778 IIRB.Int32Ty, "input_sub_type_id",
1779 "The sub type id of the input value (for arrays and vectors, or -1).",
1781 if (Config.has(PassInputSize))
1782 IRTArgs.push_back(IRTArg(IIRB.Int32Ty, "input_size",
1783 "The size of the input value.", IRTArg::NONE,
1784 getInputSize));
1785 if (!IsPRE && Config.has(PassResult))
1786 IRTArgs.push_back(
1787 IRTArg(IIRB.Int64Ty, "result", "Result of the cast.",
1790 : IRTArg::NONE),
1791 getValue, Config.has(ReplaceResult) ? replaceValue : nullptr));
1792 if (Config.has(PassResultTypeId))
1793 IRTArgs.push_back(IRTArg(IIRB.Int32Ty, "result_type_id",
1794 "The type id of the result value.", IRTArg::TYPEID,
1796 if (Config.has(PassResultSubTypeId))
1797 IRTArgs.push_back(IRTArg(
1798 IIRB.Int32Ty, "result_sub_type_id",
1799 "The sub type id of the result value (for arrays and vectors, or -1).",
1801 if (Config.has(PassResultSize))
1802 IRTArgs.push_back(IRTArg(IIRB.Int32Ty, "result_size",
1803 "The size of the result value.", IRTArg::NONE,
1804 getResultSize));
1805 if (Config.has(PassOpcode))
1806 IRTArgs.push_back(IRTArg(IIRB.Int32Ty, "opcode",
1807 "The opcode of the cast instruction.",
1809
1810 addCommonArgs(IConf, IIRB.Ctx, Config.has(PassId));
1811 IConf.addChoice(*this, IIRB.Ctx);
1812}
1813
1816 auto &CI = cast<CastInst>(V);
1817 return CI.getOperand(0);
1818}
1819
1822 auto &CI = cast<CastInst>(V);
1823 return getCI(&Ty, CI.getSrcTy()->getTypeID());
1824}
1825
1827 InstrumentationConfig &IConf,
1829 auto &CI = cast<CastInst>(V);
1830 return getSubTypeID(*CI.getSrcTy(), Ty);
1831}
1832
1835 auto &CI = cast<CastInst>(V);
1836 auto &DL = CI.getDataLayout();
1837 return getCI(&Ty, DL.getTypeStoreSize(CI.getSrcTy()));
1838}
1839
1842 auto &CI = cast<CastInst>(V);
1843 return getCI(&Ty, CI.getDestTy()->getTypeID());
1844}
1845
1847 InstrumentationConfig &IConf,
1849 auto &CI = cast<CastInst>(V);
1850 return getSubTypeID(*CI.getDestTy(), Ty);
1851}
1852
1855 auto &CI = cast<CastInst>(V);
1856 auto &DL = CI.getDataLayout();
1857 return getCI(&Ty, DL.getTypeStoreSize(CI.getDestTy()));
1858}
1859///}
1860
1863 auto &I = cast<Instruction>(V);
1864 uint64_t Flag = NUMERIC_FLAG_NONE;
1865
1866 switch (I.getOpcode()) {
1867 case Instruction::Add:
1868 case Instruction::Sub:
1869 case Instruction::Mul:
1870 case Instruction::Shl:
1871 if (I.hasNoSignedWrap())
1873 if (I.hasNoUnsignedWrap())
1875 break;
1876 case Instruction::FAdd:
1877 case Instruction::FSub:
1878 case Instruction::FMul:
1879 case Instruction::FDiv:
1880 case Instruction::FNeg:
1881 if (I.hasNoNaNs())
1883 if (I.hasNoInfs())
1885 if (I.hasNoSignedZeros())
1887 break;
1888 case Instruction::AShr:
1889 case Instruction::LShr:
1890 case Instruction::SDiv:
1891 case Instruction::UDiv:
1892 if (I.isExact())
1893 Flag |= NUMERIC_FLAG_IS_EXACT;
1894 break;
1895 }
1896
1897 if (auto *DI = dyn_cast<PossiblyDisjointInst>(&V))
1898 if (DI->isDisjoint())
1900
1901 return getCI(&Ty, Flag);
1902}
1903
1912
1914 InstrumentorIRBuilderTy &IIRB, ConfigTy *UserConfig) {
1915 if (UserConfig)
1916 Config = UserConfig;
1918 const auto ValArgOpts =
1921 if (Config.has(PassTypeId))
1922 IRTArgs.push_back(IRTArg(IIRB.Int32Ty, "type_id",
1923 "The operation's type id.", IRTArg::TYPEID,
1924 getTypeId));
1925 if (Config.has(PassSubTypeId))
1926 IRTArgs.push_back(
1927 IRTArg(IIRB.Int32Ty, "sub_type_id",
1928 "The operation's sub type id (for arrays and vectors, or -1).",
1930 if (Config.has(PassSize))
1931 IRTArgs.push_back(IRTArg(IIRB.Int32Ty, "size", "The operation's type size.",
1933 if (Config.has(PassOpcode))
1934 IRTArgs.push_back(IRTArg(IIRB.Int32Ty, "opcode", "The instruction opcode.",
1936 if (Config.has(PassLeft))
1937 IRTArgs.push_back(IRTArg(IIRB.Int64Ty, "left",
1938 "The operation's left operand.", ValArgOpts,
1940 if (Config.has(PassRight))
1941 IRTArgs.push_back(IRTArg(IIRB.Int64Ty, "right",
1942 "The operation's right operand. This value is "
1943 "poison for unary operations.",
1944 ValArgOpts, getRightOperand));
1945 if (!IsPRE && Config.has(PassResult))
1946 IRTArgs.push_back(
1947 IRTArg(IIRB.Int64Ty, "result", "Result of the operation.",
1948 IRTArg::REPLACABLE | ValArgOpts, getValue,
1949 Config.has(ReplaceResult) ? replaceValue : nullptr));
1950 if (Config.has(PassFlags))
1951 IRTArgs.push_back(
1952 IRTArg(IIRB.Int64Ty, "flags",
1953 "A bitmask value signaling which instruction flags are present.",
1955 addCommonArgs(IConf, IIRB.Ctx, Config.has(PassId));
1956 addFlagNames();
1957 IConf.addChoice(*this, IIRB.Ctx);
1958}
1959
1961 InstrumentationConfig &IConf,
1963 auto &I = cast<Instruction>(V);
1964 return getCI(&Ty, I.getOperand(0)->getType()->getTypeID());
1965}
1966
1968 InstrumentationConfig &IConf,
1970 auto &I = cast<Instruction>(V);
1971 auto &DL = I.getDataLayout();
1972 return getCI(&Ty, DL.getTypeStoreSize(I.getOperand(0)->getType()));
1973}
1974
1977 auto *CI = dyn_cast<CmpInst>(&V);
1978 return getCI(&Ty, CI->getPredicate());
1979}
1980
1987
1990 auto &I = cast<Instruction>(V);
1991 uint64_t Flag = NUMERIC_FLAG_NONE;
1992
1993 switch (I.getOpcode()) {
1994 case Instruction::ICmp:
1995 if (dyn_cast<ICmpInst>(&V)->hasSameSign())
1996 Flag |= COMPARE_FLAG_SAMESIGN;
1997 break;
1998 case Instruction::FCmp:
1999 if (I.hasNoNaNs())
2001 if (I.hasNoInfs())
2003 if (I.hasNoSignedZeros())
2005 break;
2006 }
2007
2008 return getCI(&Ty, Flag);
2009}
2010
2012 InstrumentorIRBuilderTy &IIRB, ConfigTy *UserConfig) {
2013 if (UserConfig)
2014 Config = UserConfig;
2016 const auto OperandArgOpts =
2019 if (Config.has(PassOpTypeId))
2020 IRTArgs.push_back(IRTArg(IIRB.Int32Ty, "operand_type_id",
2021 "The operand type id.", IRTArg::NONE,
2023 if (Config.has(PassOpSize))
2024 IRTArgs.push_back(IRTArg(IIRB.Int32Ty, "operand_size",
2025 "The operand type size.", IRTArg::NONE,
2027 if (Config.has(PassOpcode))
2028 IRTArgs.push_back(IRTArg(IIRB.Int32Ty, "opcode", "The instruction opcode.",
2030 if (Config.has(PassPredicate))
2031 IRTArgs.push_back(IRTArg(IIRB.Int32Ty, "predicate",
2032 "The comparison predicate ID.", IRTArg::NONE,
2033 getPredicate));
2034 if (Config.has(PassLeft))
2035 IRTArgs.push_back(IRTArg(IIRB.Int64Ty, "left",
2036 "The comparison's left operand.", OperandArgOpts,
2038 if (Config.has(PassRight))
2039 IRTArgs.push_back(IRTArg(IIRB.Int64Ty, "right",
2040 "The comparison's right operand.", OperandArgOpts,
2042 if (!IsPRE && Config.has(PassResultSize))
2043 IRTArgs.push_back(IRTArg(IIRB.Int32Ty, "result_type_id",
2044 "The result value's type ID.", IRTArg::NONE,
2045 getTypeId));
2046 if (!IsPRE && Config.has(PassResultSize))
2047 IRTArgs.push_back(IRTArg(IIRB.Int32Ty, "result_size",
2048 "Size of the result value.", IRTArg::NONE,
2049 getTypeSize));
2050 if (!IsPRE && Config.has(PassResult))
2051 IRTArgs.push_back(
2052 IRTArg(IIRB.Int64Ty, "result", "Result of the operation.",
2055 : IRTArg::NONE),
2056 getValue, Config.has(ReplaceResult) ? replaceValue : nullptr));
2057 if (Config.has(PassFlags))
2058 IRTArgs.push_back(
2059 IRTArg(IIRB.Int64Ty, "flags",
2060 "A bitmask value signaling which instruction flags are present.",
2062 addFlagNames();
2063 addCommonArgs(IConf, IIRB.Ctx, Config.has(PassId));
2064 IConf.addChoice(*this, IIRB.Ctx);
2065}
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:1567
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:69
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:83
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:477
const std::string & getTriple() const
Definition Triple.h:580
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:288
bool isPointerTy() const
True if this is an instance of PointerType.
Definition Type.h:282
bool isAggregateType() const
Return true if the type is an aggregate type.
Definition Type.h:319
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:257
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:255
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:380
bool hasName() const
Definition Value.h:261
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
Definition Value.cpp:319
constexpr ScalarTy getFixedValue() const
Definition TypeSize.h:200
constexpr bool isFixed() const
Returns true if the quantity is not scaled by vscale.
Definition TypeSize.h:171
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:2554
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:2208
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:551
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 const Value * getUnderlyingObjectAggressive(const Value *V)
Like getUnderlyingObject(), but will try harder to find a single underlying object.
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:2192
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, bool MatchType=false)
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