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 <system_error>
65#include <type_traits>
66
67using namespace llvm;
68using namespace llvm::instrumentor;
69
70#define DEBUG_TYPE "instrumentor"
71
72namespace {
73
74/// The user option to specify an output JSON file to write the configuration.
75static cl::opt<std::string> OutputConfigFile(
76 "instrumentor-write-config-file",
78 "Write the instrumentor configuration into the specified JSON file"),
79 cl::init(""));
80
81/// The user option to specify input JSON files to read the configuration from.
83 ConfigFiles("instrumentor-read-config-files",
84 cl::desc("Read the instrumentor configuration from the "
85 "specified JSON files (comma separated)"),
87
88/// The user option to specify an input file to read the configuration file
89/// paths from.
90static cl::opt<std::string> ConfigPathsFile(
91 "instrumentor-read-config-paths-file",
92 cl::desc("Read the instrumentor configuration file "
93 "paths from the specified file (newline separated)"),
94 cl::init(""));
95
96/// Set the debug location, if not set, after changing the insertion point of
97/// the IR builder \p IRB.
98template <typename IRBuilderTy> void ensureDbgLoc(IRBuilderTy &IRB) {
99 if (IRB.getCurrentDebugLocation())
100 return;
101 auto *BB = IRB.GetInsertBlock();
102 if (auto *SP = BB->getParent()->getSubprogram())
103 IRB.SetCurrentDebugLocation(DILocation::get(BB->getContext(), 0, 0, SP));
104}
105
106/// Attempt to cast \p V to type \p Ty using only bit-preserving casts.
107/// This ensures that floating-point values are converted via bitcast (not
108/// fptosi/fptoui) to preserve their exact bit representation.
109template <typename IRBTy>
110Value *tryToCast(IRBTy &IRB, Value *V, Type *Ty, const DataLayout &DL,
111 bool AllowTruncate = false) {
112 if (!V)
113 return Constant::getAllOnesValue(Ty);
114 Type *VTy = V->getType();
115 if (VTy == Ty)
116 return V;
117 if (VTy->isAggregateType() || VTy->isVectorTy())
118 return V;
119 if (VTy->isPointerTy() && Ty->isPointerTy())
120 return IRB.CreatePointerBitCastOrAddrSpaceCast(V, Ty);
121 TypeSize RequestedSize = DL.getTypeSizeInBits(Ty);
122 TypeSize ValueSize = DL.getTypeSizeInBits(VTy);
123 bool ShouldTruncate = RequestedSize < ValueSize;
124 if (ShouldTruncate && !AllowTruncate)
125 return V;
126 if (ShouldTruncate && AllowTruncate) {
127 // First convert to integer of the same size if needed.
128 Value *IntV = V;
129 if (VTy->isFloatingPointTy())
130 IntV = IRB.CreateBitCast(V, IRB.getIntNTy(ValueSize));
131 return tryToCast(IRB,
132 IRB.CreateIntCast(IntV, IRB.getIntNTy(RequestedSize),
133 /*IsSigned=*/false),
134 Ty, DL, AllowTruncate);
135 }
136 if (VTy->isIntegerTy() && Ty->isIntegerTy())
137 return IRB.CreateIntCast(V, Ty, /*IsSigned=*/false);
138 // Use bit-preserving casts for floating-point values: convert float to int
139 // of the same size via bitcast, then extend/truncate the integer if needed.
140 if (VTy->isFloatingPointTy() && Ty->isIntOrPtrTy()) {
141 return tryToCast(IRB, IRB.CreateBitCast(V, IRB.getIntNTy(ValueSize)), Ty,
142 DL, AllowTruncate);
143 }
144 // When converting int to float, never use sitofp/uitofp as they perform value
145 // conversion, not bit-preserving cast.
146 if (VTy->isIntegerTy() && Ty->isFloatingPointTy()) {
147 if (ValueSize == RequestedSize)
148 return IRB.CreateBitCast(V, Ty);
149 return tryToCast(
150 IRB,
151 IRB.CreateIntCast(V, IRB.getIntNTy(RequestedSize), /*IsSigned=*/false),
152 Ty, DL, AllowTruncate);
153 }
154 return IRB.CreateBitOrPointerCast(V, Ty);
155}
156
157/// Get a constant integer/boolean of type \p IT and value \p Val.
158template <typename Ty>
159Constant *getCI(Type *IT, Ty Val, bool IsSigned = false) {
160 return ConstantInt::get(IT, Val, IsSigned);
161}
162
163Constant *getSubTypeID(Type &OpTy, Type &ReqTy) {
164 switch (OpTy.getTypeID()) {
165 case Type::TypeID::ArrayTyID:
166 case Type::TypeID::FixedVectorTyID:
167 case Type::TypeID::ScalableVectorTyID:
168 return getCI(&ReqTy, OpTy.getContainedType(0)->getTypeID());
169 default:
170 break;
171 }
172
173 return getCI(&ReqTy, -1, /*IsSigned=*/true);
174}
175
176/// The core of the instrumentor pass, which instruments the module as the
177/// instrumentation configuration mandates.
178class InstrumentorImpl final {
179public:
180 /// Construct an instrumentor implementation using the configuration \p IConf.
181 InstrumentorImpl(InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB,
182 Module &M)
183 : IConf(IConf), M(M), IIRB(IIRB) {}
184
185 /// Instrument the module, public entry point.
186 bool instrument();
187
188 // Reset the state to allow reuse of the instrumentor with a different
189 // configuration.
190 void clear() {
191 InstChoicesPRE.clear();
192 InstChoicesPOST.clear();
193 ParsedFunctionRegex = Regex();
194 }
195
196private:
197 void linkRuntime();
198
199 /// Indicate if the module should be instrumented based on the target.
200 bool shouldInstrumentTarget();
201
202 /// Indicate if the function \p Fn should be instrumented.
203 bool shouldInstrumentFunction(Function &Fn);
204 bool shouldInstrumentGlobalVariable(GlobalVariable &GV);
205
206 /// Instrument instruction \p I if needed, and use the argument caches in \p
207 /// ICaches.
208 bool instrumentInstruction(Instruction &I, InstrumentationCaches &ICaches);
209
210 /// Instrument function \p Fn.
211 bool instrumentFunction(Function &Fn);
212 bool instrumentModule();
213
214 /// The instrumentation opportunities for instructions indexed by
215 /// their opcode.
217 InstChoicesPOST;
218
219 /// The instrumentor configuration.
221
222 /// The function regex filter, if any.
223 Regex ParsedFunctionRegex;
224
225 /// The underlying module.
226 Module &M;
227
228protected:
229 /// A special IR builder that keeps track of the inserted instructions.
231};
232
233} // end anonymous namespace
234
236 if (!Str.empty()) {
237 Regex RX(Str);
238 std::string ErrMsg;
239 if (!RX.isValid(ErrMsg)) {
241 Twine("failed to parse ") + Name + " regex: " + ErrMsg, DS_Error));
242 return Regex();
243 }
244 return RX;
245 }
246 return Regex();
247}
248
249void InstrumentorImpl::linkRuntime() {
250 const auto RuntimeBitcode = IConf.RuntimeBitcode->getString();
251 if (RuntimeBitcode.empty())
252 return;
253
254 SMDiagnostic Err;
255 auto RTM = parseIRFile(RuntimeBitcode, Err, M.getContext());
256 if (!RTM) {
257 IIRB.Ctx.diagnose(DiagnosticInfoInstrumentation(
258 Twine("Failed to parse runtime bitcode file '") + RuntimeBitcode +
259 Twine("':\n") + M.getName(),
260 DS_Error));
261 return;
262 }
263
264 auto InternalizeCallback = [&](Module &M, const StringSet<> &GVS) {
265 internalizeModule(M, [&GVS](const GlobalValue &GV) {
266 return !GV.hasName() || !GVS.count(GV.getName());
267 });
268 };
269
270 if (Linker::linkModules(M, std::move(RTM), 0, InternalizeCallback)) {
271 IIRB.Ctx.diagnose(DiagnosticInfoInstrumentation(
272 "Failed to link in runtime bitcode", DS_Error));
273 return;
274 }
275
276 if (!IConf.InlineRuntimeEagerly->getBool())
277 return;
278
279 for (auto [I, _] : IIRB.NewInsts) {
280 auto *CI = dyn_cast<CallInst>(I);
281 if (!CI || isa<IntrinsicInst>(CI))
282 continue;
283
284 InlineFunctionInfo IFI;
285 auto InlineResult = InlineFunction(*CI, IFI);
286 if (!InlineResult.isSuccess()) {
287 std::string WarnMsg;
288 raw_string_ostream SS(WarnMsg);
289 SS << "Inlining of runtime call failed: "
290 << CI->getCalledFunction()->getName() << "\n";
291 SS << "Reason: " << InlineResult.getFailureReason() << "\n";
292 SS << "Signatures: " << *CI->getFunctionType() << " vs "
293 << *CI->getCalledFunction()->getFunctionType() << "\n";
294 IIRB.Ctx.diagnose(DiagnosticInfoInstrumentation(WarnMsg, DS_Warning));
295 }
296 }
297
298 // Promote any eligible instrumentor-associated allocas to registers.
299 for (auto It : IIRB.AllocaMap) {
300 auto *Fn = It.first.first;
301 DominatorTree DT(*Fn);
302 auto &Allocas = *It.second;
303 erase_if(Allocas,
304 [](const AllocaInst *AI) { return !isAllocaPromotable(AI); });
305 PromoteMemToReg(Allocas, DT);
306 delete It.second;
307 }
308 IIRB.AllocaMap.clear();
309}
310
311bool InstrumentorImpl::shouldInstrumentTarget() {
312 const Triple &T = M.getTargetTriple();
313 const bool IsGPU = T.isAMDGPU() || T.isNVPTX();
314
315 bool RegexMatches = true;
316 Regex RX = createRegex(IConf.TargetRegex->getString(), "target", IIRB.Ctx);
317 if (RX.isValid())
318 RegexMatches = RX.match(T.str());
319
320 // Only instrument the module if the target has to be instrumented.
321 return ((IsGPU && IConf.GPUEnabled->getBool()) ||
322 (!IsGPU && IConf.HostEnabled->getBool())) &&
323 RegexMatches;
324}
325
326bool InstrumentorImpl::shouldInstrumentFunction(Function &Fn) {
327 if (Fn.isDeclaration())
328 return false;
329 bool RegexMatches = true;
330 if (ParsedFunctionRegex.isValid())
331 RegexMatches = ParsedFunctionRegex.match(Fn.getName());
332 return (RegexMatches && !Fn.getName().starts_with(IConf.getRTName())) ||
333 Fn.hasFnAttribute("instrument");
334}
335
336bool InstrumentorImpl::shouldInstrumentGlobalVariable(GlobalVariable &GV) {
337 return !GV.getName().starts_with("llvm.") &&
338 !GV.getName().starts_with(IConf.getRTName());
339}
340
341bool InstrumentorImpl::instrumentInstruction(Instruction &I,
342 InstrumentationCaches &ICaches) {
343 bool Changed = false;
344
345 // Skip instrumentation instructions.
346 if (IIRB.NewInsts.contains(&I))
347 return Changed;
348
349 // Count epochs eagerly.
350 ++IIRB.Epoch;
351
352 Value *IPtr = &I;
353 if (auto *IO = InstChoicesPRE.lookup(I.getOpcode())) {
354 IIRB.IRB.SetInsertPoint(&I);
355 ensureDbgLoc(IIRB.IRB);
356 IO->instrument(IPtr, Changed, IConf, IIRB, ICaches);
357 }
358
359 if (auto *IO = InstChoicesPOST.lookup(I.getOpcode())) {
360 IIRB.IRB.SetInsertPoint(I.getNextNode());
361 ensureDbgLoc(IIRB.IRB);
362 IO->instrument(IPtr, Changed, IConf, IIRB, ICaches);
363 }
364 IIRB.returnAllocas();
365
366 return Changed;
367}
368
369bool InstrumentorImpl::instrumentFunction(Function &Fn) {
370 bool Changed = false;
371 if (!shouldInstrumentFunction(Fn))
372 return Changed;
373
374 InstrumentationCaches ICaches;
375 SmallVector<Instruction *> FinalTIs;
376 ReversePostOrderTraversal<Function *> RPOT(&Fn);
377 for (auto &It : RPOT) {
378 for (auto &I : *It)
379 Changed |= instrumentInstruction(I, ICaches);
380
381 auto *TI = It->getTerminator();
382 if (!TI->getNumSuccessors())
383 FinalTIs.push_back(TI);
384 }
385
386 Value *FPtr = &Fn;
387 for (auto &[Name, IO] :
389 if (!IO->Enabled)
390 continue;
391 // Count epochs eagerly.
392 ++IIRB.Epoch;
393
394 IIRB.IRB.SetInsertPoint(
395 cast<Function>(FPtr)->getEntryBlock().getFirstNonPHIOrDbgOrAlloca());
396 ensureDbgLoc(IIRB.IRB);
397 IO->instrument(FPtr, Changed, IConf, IIRB, ICaches);
398 IIRB.returnAllocas();
399 }
400
401 for (auto &[Name, IO] :
403 if (!IO->Enabled)
404 continue;
405 // Count epochs eagerly.
406 ++IIRB.Epoch;
407
408 for (Instruction *FinalTI : FinalTIs) {
409 IIRB.IRB.SetInsertPoint(FinalTI);
410 ensureDbgLoc(IIRB.IRB);
411 IO->instrument(FPtr, Changed, IConf, IIRB, ICaches);
412 IIRB.returnAllocas();
413 }
414 }
415 return Changed;
416}
417
418bool InstrumentorImpl::instrumentModule() {
420 Globals.reserve(M.global_size());
421 for (GlobalVariable &GV : M.globals()) {
422 // llvm.metadata contains globals such as llvm.used.
423 if (GV.getSection() == "llvm.metadata" ||
424 GV.getName() == "llvm.global_dtors" ||
425 GV.getName() == "llvm.global_ctors")
426 continue;
427 Globals.push_back(&GV);
428 }
429
430 auto CreateYtor = [&](bool Ctor) {
431 Function *YtorFn = Function::Create(
432 FunctionType::get(IIRB.VoidTy, false), GlobalValue::PrivateLinkage,
433 IConf.getRTName(Ctor ? "ctor" : "dtor", ""), M);
434
435 auto *EntryBB = BasicBlock::Create(IIRB.Ctx, "entry", YtorFn);
436 IIRB.IRB.SetInsertPoint(EntryBB, EntryBB->begin());
437 ensureDbgLoc(IIRB.IRB);
438 IIRB.IRB.CreateRetVoid();
439
440 if (Ctor)
441 appendToGlobalCtors(M, YtorFn, 1000);
442 else
443 appendToGlobalDtors(M, YtorFn, 1000);
444 return YtorFn;
445 };
446
447 InstrumentationCaches ICaches;
448
449 Function *CtorFn = nullptr, *DtorFn = nullptr;
450 bool Changed = false;
453 bool IsPRE = InstrumentationLocation::isPRE(Loc);
454 Function *&YtorFn = IsPRE ? CtorFn : DtorFn;
455 for (auto &ChoiceIt : IConf.IChoices[Loc]) {
456 auto *IO = ChoiceIt.second;
457 if (!IO->Enabled)
458 continue;
459 if (!YtorFn) {
460 YtorFn = CreateYtor(IsPRE);
461 Changed = true;
462 }
463 IIRB.IRB.SetInsertPointPastAllocas(YtorFn);
464 ensureDbgLoc(IIRB.IRB);
465 Value *YtorPtr = YtorFn;
466
467 // Count epochs eagerly.
468 ++IIRB.Epoch;
469
470 IO->instrument(YtorPtr, Changed, IConf, IIRB, ICaches);
471 IIRB.returnAllocas();
472 }
473 }
474
477 bool IsPRE = InstrumentationLocation::isPRE(Loc);
478 Function *&YtorFn = IsPRE ? CtorFn : DtorFn;
479 for (auto &ChoiceIt : IConf.IChoices[Loc]) {
480 auto *IO = ChoiceIt.second;
481 if (!IO->Enabled)
482 continue;
483 if (!YtorFn) {
484 YtorFn = CreateYtor(IsPRE);
485 Changed = true;
486 }
487 for (GlobalVariable *GV : Globals) {
488 if (!shouldInstrumentGlobalVariable(*GV))
489 continue;
490 if (IsPRE)
491 IIRB.IRB.SetInsertPoint(YtorFn->getEntryBlock().getTerminator());
492 else
493 IIRB.IRB.SetInsertPointPastAllocas(YtorFn);
494 ensureDbgLoc(IIRB.IRB);
495 Value *GVPtr = GV;
496
497 // Count epochs eagerly.
498 ++IIRB.Epoch;
499
500 IO->instrument(GVPtr, Changed, IConf, IIRB, ICaches);
501 IIRB.returnAllocas();
502 }
503 }
504 }
505
506 return Changed;
507}
508
509bool InstrumentorImpl::instrument() {
510 bool Changed = false;
511 if (!shouldInstrumentTarget())
512 return Changed;
513
514 StringRef FunctionRegexStr = IConf.FunctionRegex->getString();
515 ParsedFunctionRegex = createRegex(FunctionRegexStr, "function", IIRB.Ctx);
516
517 // Helper to register an IO for all its opcodes.
518 auto RegisterForAllOpcodes = [](auto &InstChoices,
519 InstrumentationOpportunity *IO) {
520 ArrayRef<unsigned> Opcodes = IO->getAllOpcodes();
521 // Register for all opcodes.
522 for (unsigned Opcode : Opcodes)
523 InstChoices[Opcode] = IO;
524 };
525
526 for (auto &[Name, IO] :
528 if (IO->Enabled)
529 RegisterForAllOpcodes(InstChoicesPRE, IO);
530 for (auto &[Name, IO] :
532 if (IO->Enabled)
533 RegisterForAllOpcodes(InstChoicesPOST, IO);
534 Changed |= instrumentModule();
535
536 for (Function &Fn : M)
537 Changed |= instrumentFunction(Fn);
538
539 linkRuntime();
540
541 return Changed;
542}
543
545 InstrumentationConfig *IC,
546 InstrumentorIRBuilderTy *IIRB)
547 : FS(FS), UserIConf(IC), UserIIRB(IIRB) {
548 if (!FS)
549 this->FS = vfs::getRealFileSystem();
550}
551
552PreservedAnalyses InstrumentorPass::run(Module &M, InstrumentationConfig &IConf,
554 bool ReadConfig) {
555 bool Changed = false;
556 InstrumentorImpl Impl(IConf, IIRB, M);
557
558 // If this is a configuration driven run, iterate over all configurations
559 // provided by the user, if not, use the config as is and run the instrumentor
560 // once.
561 if (ReadConfig)
562 readConfigPathsFile(ConfigPathsFile, ConfigFiles, IIRB.Ctx, *FS);
563
564 bool MultipleConfigs = ConfigFiles.size() > 1;
565 unsigned Idx = 0;
566 do {
567 std::string ConfigFile =
568 ReadConfig && !ConfigFiles.empty() ? ConfigFiles[Idx] : "";
569
570 // Initialize the config to the base state but keep the caches around.
571 Impl.clear();
572 IConf.init(IIRB);
573
574 if (!readConfigFromJSON(IConf, ConfigFile, IIRB.Ctx, *FS))
575 continue;
576
577 writeConfigToJSON(IConf,
578 MultipleConfigs
579 ? OutputConfigFile + "." + std::to_string(Idx)
580 : OutputConfigFile,
581 IIRB.Ctx);
582
583 printRuntimeStub(IConf, IConf.RuntimeStubsFile->getString(), IIRB.Ctx);
584
585 Changed |= Impl.instrument();
586 } while (++Idx < ConfigFiles.size());
587
588 if (!Changed)
589 return PreservedAnalyses::all();
591}
592
594 // Only create them if the user did not provide them.
595 std::unique_ptr<InstrumentationConfig> IConfInt(
596 !UserIConf ? new InstrumentationConfig() : nullptr);
597 std::unique_ptr<InstrumentorIRBuilderTy> IIRBInt(
598 !UserIIRB ? new InstrumentorIRBuilderTy(M) : nullptr);
599
600 auto *IConf = IConfInt ? IConfInt.get() : UserIConf;
601 auto *IIRB = IIRBInt ? IIRBInt.get() : UserIIRB;
602
603 auto PA = run(M, *IConf, *IIRB, !UserIConf);
604
605 assert(!verifyModule(M, &errs()));
606 return PA;
607}
608
609std::unique_ptr<BaseConfigurationOption>
612 bool DefaultValue) {
613 auto BCO =
614 std::make_unique<BaseConfigurationOption>(Name, Description, BOOLEAN);
615 BCO->setBool(DefaultValue);
616 IConf.addBaseChoice(BCO.get());
617 return BCO;
618}
619
620std::unique_ptr<BaseConfigurationOption>
624 StringRef DefaultValue) {
625 auto BCO =
626 std::make_unique<BaseConfigurationOption>(Name, Description, STRING);
627 BCO->setString(DefaultValue);
628 IConf.addBaseChoice(BCO.get());
629 return BCO;
630}
631
633 /// List of all instrumentation opportunities.
634 BasePointerIO::populate(*this, IIRB);
635 ModuleIO::populate(*this, IIRB);
636 GlobalVarIO::populate(*this, IIRB);
637 FunctionIO::populate(*this, IIRB);
638 AllocaIO::populate(*this, IIRB);
639 UnreachableIO::populate(*this, IIRB);
640 LoadIO::populate(*this, IIRB);
641 StoreIO::populate(*this, IIRB);
642 CastIO::populate(*this, IIRB);
643 NumericIO::populate(*this, IIRB);
644 CompareIO::populate(*this, IIRB);
645}
646
648 LLVMContext &Ctx) {
649 auto *&ICPtr = IChoices[IO.getLocationKind()][IO.getName()];
650 if (ICPtr) {
652 Twine("registered two instrumentation opportunities for the same "
653 "location (") +
654 ICPtr->getName() + Twine(" vs ") + IO.getName() + Twine(")"),
655 DS_Warning));
656 }
657 ICPtr = &IO;
658}
659
660Value *
663 Function *Fn = IIRB.IRB.GetInsertBlock()->getParent();
664
665 Value *Obj;
666 {
667 Value *&UnderlyingObj = UnderlyingObjsMap[&V];
668 if (!UnderlyingObj)
669 UnderlyingObj = const_cast<Value *>(getUnderlyingObjectAggressive(&V));
670 Obj = UnderlyingObj;
671 }
672
673 Value *&BPI = BasePointerInfoMap[{Obj, Fn}];
674 if (BPI)
675 return BPI;
676
677 auto *BPIO =
679 if (!BPIO || !BPIO->Enabled) {
681 "Base pointer info disabled but required, passing nullptr.",
682 DS_Warning));
683 return BPI = Constant::getNullValue(BPIO->getRetTy(IIRB.Ctx));
684 }
685
687 if (auto *BasePtrI = dyn_cast<Instruction>(Obj)) {
688 std::optional<BasicBlock::iterator> IP =
689 BasePtrI->getInsertionPointAfterDef();
690 if (IP) {
691 IIRB.IRB.SetInsertPoint(*IP);
692 } else {
694 "Base pointer info could not be placed, passing nullptr.",
695 DS_Warning));
696 return BPI = Constant::getNullValue(BPIO->getRetTy(IIRB.Ctx));
697 }
698 } else if (isa<Constant>(Obj) || isa<Argument>(Obj)) {
699 IIRB.IRB.SetInsertPointPastAllocas(IIRB.IRB.GetInsertBlock()->getParent());
700 } else {
701 LLVM_DEBUG(Obj->dump());
702 llvm_unreachable("Unexpected base pointer!");
703 }
704 ensureDbgLoc(IIRB.IRB);
705
706 // Use fresh caches for safety, as this function may be called from
707 // another instrumentation opportunity.
708 bool Changed;
709 InstrumentationCaches ICaches;
710 BPI = BPIO->instrument(Obj, Changed, *this, IIRB, ICaches);
711 IIRB.returnAllocas();
712 if (!BPI)
713 BPI = Constant::getNullValue(BPIO->getRetTy(IIRB.Ctx));
714 return BPI;
715}
716
720 return getCI(&Ty, getIdFromEpoch(IIRB.Epoch));
721}
722
726 return getCI(&Ty, -getIdFromEpoch(IIRB.Epoch), /*IsSigned=*/true);
727}
728
731 if (V.getType()->isVoidTy())
732 return Ty.isVoidTy() ? &V : Constant::getNullValue(&Ty);
733 return tryToCast(IIRB.IRB, &V, &Ty,
734 IIRB.IRB.GetInsertBlock()->getDataLayout());
735}
736
740 if (V.getType()->isVoidTy())
741 return &V;
742
743 auto *NewVCasted = &NewV;
744 if (auto *I = dyn_cast<Instruction>(&NewV)) {
746 IIRB.IRB.SetInsertPoint(I->getNextNode());
747 ensureDbgLoc(IIRB.IRB);
748 NewVCasted = tryToCast(IIRB.IRB, &NewV, V.getType(), IIRB.DL,
749 /*AllowTruncate=*/true);
750 }
751 V.replaceUsesWithIf(NewVCasted, [&](Use &U) {
752 if (IIRB.NewInsts.lookup(cast<Instruction>(U.getUser())) == IIRB.Epoch)
753 return false;
754 return !isa<LifetimeIntrinsic>(U.getUser()) && !U.getUser()->isDroppable();
755 });
756
757 return &V;
758}
759
761 Type *RetTy)
762 : IO(IO), RetTy(RetTy) {
763 for (auto &It : IO.IRTArgs) {
764 if (!It.Enabled)
765 continue;
766 NumReplaceableArgs += bool(It.Flags & IRTArg::REPLACABLE);
767 MightRequireIndirection |= It.Flags & IRTArg::POTENTIALLY_INDIRECT;
768 }
771}
772
775 const DataLayout &DL, bool ForceIndirection) {
776 assert(((ForceIndirection && MightRequireIndirection) ||
777 (!ForceIndirection && !RequiresIndirection)) &&
778 "Wrong indirection setting!");
779
780 SmallVector<Type *> ParamTypes;
781 for (auto &It : IO.IRTArgs) {
782 if (!It.Enabled)
783 continue;
784 if (!ForceIndirection || !isPotentiallyIndirect(It)) {
785 ParamTypes.push_back(It.Ty);
786 if (!RetTy && NumReplaceableArgs == 1 && (It.Flags & IRTArg::REPLACABLE))
787 RetTy = It.Ty;
788 continue;
789 }
790
791 // The indirection pointer and the size of the value.
792 ParamTypes.push_back(IIRB.PtrTy);
793 if (!(It.Flags & IRTArg::INDIRECT_HAS_SIZE))
794 ParamTypes.push_back(IIRB.Int32Ty);
795 }
796 if (!RetTy)
797 RetTy = IIRB.VoidTy;
798
799 return FunctionType::get(RetTy, ParamTypes, /*isVarArg=*/false);
800}
801
805 const DataLayout &DL,
806 InstrumentationCaches &ICaches) {
807 SmallVector<Value *> CallParams;
808
810 auto IP = IIRB.IRB.GetInsertPoint();
811
812 bool ForceIndirection = RequiresIndirection;
813 for (auto &It : IO.IRTArgs) {
814 if (!It.Enabled)
815 continue;
816 auto *&Param = ICaches.DirectArgCache[{IIRB.Epoch, IO.getName(), It.Name}];
817 if (!Param || It.NoCache)
818 // Avoid passing the caches to the getter.
819 Param = It.GetterCB(*V, *It.Ty, IConf, IIRB);
820 assert(Param);
821
822 if (Param->getType()->isVoidTy()) {
823 Param = Constant::getNullValue(It.Ty);
824 } else if (Param->getType()->isAggregateType() ||
825 Param->getType()->isVectorTy() ||
826 DL.getTypeSizeInBits(Param->getType()) >
827 DL.getTypeSizeInBits(It.Ty)) {
828 if (!isPotentiallyIndirect(It)) {
830 Twine("indirection needed for ") + It.Name + Twine(" in ") +
831 IO.getName() +
832 Twine(", but not indicated. Instrumentation is skipped"),
833 DS_Warning));
834 return nullptr;
835 }
836 ForceIndirection = true;
837 } else {
838 Param = tryToCast(IIRB.IRB, Param, It.Ty, DL);
839 }
840 CallParams.push_back(Param);
841 }
842
843 if (ForceIndirection) {
844 Function *Fn = IIRB.IRB.GetInsertBlock()->getParent();
845
846 unsigned Offset = 0;
847 for (auto &It : IO.IRTArgs) {
848 if (!It.Enabled)
849 continue;
850
851 if (!isPotentiallyIndirect(It)) {
852 ++Offset;
853 continue;
854 }
855 auto *&CallParam = CallParams[Offset++];
856 if (!(It.Flags & IRTArg::INDIRECT_HAS_SIZE)) {
857 CallParams.insert(&CallParam + 1, IIRB.IRB.getInt32(DL.getTypeStoreSize(
858 CallParam->getType())));
859 Offset += 1;
860 }
861
862 auto *&CachedParam =
863 ICaches.IndirectArgCache[{IIRB.Epoch, IO.getName(), It.Name}];
864 if (CachedParam) {
865 CallParam = CachedParam;
866 continue;
867 }
868
869 auto *AI = IIRB.getAlloca(Fn, CallParam->getType());
870 IIRB.IRB.CreateStore(CallParam, AI);
871 CallParam = CachedParam = tryToCast(IIRB.IRB, AI, IIRB.PtrTy, DL);
872 }
873 }
874
875 if (!ForceIndirection)
876 IIRB.IRB.SetInsertPoint(IP);
877 ensureDbgLoc(IIRB.IRB);
878
879 auto *FnTy = createLLVMSignature(IConf, IIRB, DL, ForceIndirection);
880 auto CompleteName =
881 IConf.getRTName(IO.IP.isPRE() ? "pre_" : "post_", IO.getName(),
882 ForceIndirection ? "_ind" : "");
883 auto FC = IIRB.IRB.GetInsertBlock()->getModule()->getOrInsertFunction(
884 CompleteName, FnTy);
885 auto *CI = IIRB.IRB.CreateCall(FC, CallParams);
886 CI->addFnAttr(Attribute::get(IIRB.Ctx, Attribute::WillReturn));
887
888 for (unsigned I = 0, E = IO.IRTArgs.size(); I < E; ++I) {
889 if (!IO.IRTArgs[I].Enabled)
890 continue;
891 if (!isReplacable(IO.IRTArgs[I]))
892 continue;
893 bool IsCustomReplaceable = IO.IRTArgs[I].Flags & IRTArg::REPLACABLE_CUSTOM;
894 Value *NewValue = FnTy->isVoidTy() || IsCustomReplaceable
895 ? ICaches.DirectArgCache[{IIRB.Epoch, IO.getName(),
896 IO.IRTArgs[I].Name}]
897 : CI;
898 assert(NewValue);
899 if (ForceIndirection && !IsCustomReplaceable &&
900 isPotentiallyIndirect(IO.IRTArgs[I])) {
901 auto *Q =
902 ICaches
903 .IndirectArgCache[{IIRB.Epoch, IO.getName(), IO.IRTArgs[I].Name}];
904 NewValue = IIRB.IRB.CreateLoad(V->getType(), Q);
905 }
906 V = IO.IRTArgs[I].SetterCB(*V, *NewValue, IConf, IIRB);
907 }
908 return CI;
909}
910
911template <typename Ty> constexpr static Value *getValue(Ty &ValueOrUse) {
912 if constexpr (std::is_same<Ty, Use>::value)
913 return ValueOrUse.get();
914 else
915 return static_cast<Value *>(&ValueOrUse);
916}
917
918template <typename Range>
921 auto *Fn = IIRB.IRB.GetInsertBlock()->getParent();
922 auto *I32Ty = IIRB.IRB.getInt32Ty();
923 SmallVector<Constant *> ConstantValues;
926 for (auto &RE : R) {
927 Value *V = getValue(RE);
928 if (!V->getType()->isSized())
929 continue;
930 auto VSize = IIRB.DL.getTypeAllocSize(V->getType());
931 ConstantValues.push_back(getCI(I32Ty, VSize));
932 Types.push_back(I32Ty);
933 ConstantValues.push_back(getCI(I32Ty, V->getType()->getTypeID()));
934 Types.push_back(I32Ty);
935 if (uint32_t MisAlign = VSize % 8) {
936 Types.push_back(ArrayType::get(IIRB.Int8Ty, 8 - MisAlign));
937 ConstantValues.push_back(ConstantArray::getNullValue(Types.back()));
938 }
939 Types.push_back(V->getType());
940 if (auto *C = dyn_cast<Constant>(V)) {
941 ConstantValues.push_back(C);
942 continue;
943 }
944 Values.push_back({V, ConstantValues.size()});
945 ConstantValues.push_back(Constant::getNullValue(V->getType()));
946 }
947 if (Types.empty())
948 return ConstantPointerNull::get(IIRB.PtrTy);
949
950 StructType *STy = StructType::get(Fn->getContext(), Types, /*isPacked=*/true);
951 Constant *Initializer = ConstantStruct::get(STy, ConstantValues);
952
953 GlobalVariable *&GV = IConf.ConstantGlobalsCache[Initializer];
954 if (!GV)
955 GV = new GlobalVariable(*Fn->getParent(), STy, false,
956 GlobalValue::InternalLinkage, Initializer,
957 IConf.getRTName("", "value_pack"));
958
959 auto *AI = IIRB.getAlloca(Fn, STy);
960 IIRB.IRB.CreateMemCpy(AI, AI->getAlign(), GV, MaybeAlign(GV->getAlignment()),
961 IIRB.DL.getTypeAllocSize(STy));
962 for (auto [Param, Idx] : Values) {
963 auto *Ptr = IIRB.IRB.CreateStructGEP(STy, AI, Idx);
964 IIRB.IRB.CreateStore(Param, Ptr);
965 }
966 return AI;
967}
968
969template <typename Range>
970static void readValuePack(const Range &R, Value &Pack,
972 function_ref<void(int, Value *)> SetterCB) {
973 auto *Fn = IIRB.IRB.GetInsertBlock()->getParent();
974 auto &DL = Fn->getDataLayout();
975 SmallVector<Value *> ParameterValues;
976 unsigned Offset = 0;
977 for (const auto &[Idx, RE] : enumerate(R)) {
978 Value *V = getValue(RE);
979 if (!V->getType()->isSized())
980 continue;
981 Offset += 8;
982 auto VSize = DL.getTypeAllocSize(V->getType());
983 auto Padding = alignTo(VSize, 8) - VSize;
984 Offset += Padding;
985 auto *Ptr = IIRB.IRB.CreateConstInBoundsGEP1_32(IIRB.Int8Ty, &Pack, Offset);
986 auto *NewV = IIRB.IRB.CreateLoad(V->getType(), Ptr);
987 SetterCB(Idx, NewV);
988 Offset += VSize;
989 }
990}
991
995 auto &I = cast<Instruction>(V);
996 return getCI(&Ty, I.getOpcode());
997}
998
1000 InstrumentationConfig &IConf,
1002 auto &I = cast<Instruction>(V);
1003 auto &DL = I.getDataLayout();
1004 return getCI(&Ty, DL.getTypeStoreSize(V.getType()));
1005}
1006
1008 InstrumentationConfig &IConf,
1010 auto &I = cast<Instruction>(V);
1011 return I.getOperand(0);
1012}
1013
1015 InstrumentationConfig &IConf,
1017 auto &I = cast<Instruction>(V);
1018 if (I.getNumOperands() > 1)
1019 return I.getOperand(1);
1020 return PoisonValue::get(&Ty);
1021}
1022
1024 InstrumentationConfig &IConf,
1026 return getCI(&Ty, V.getType()->getTypeID());
1027}
1028
1030 InstrumentationConfig &IConf,
1032 return getSubTypeID(*V.getType(), Ty);
1033}
1034
1035/// FunctionIO
1036/// {
1038 InstrumentorIRBuilderTy &IIRB, ConfigTy *UserConfig) {
1039 using namespace std::placeholders;
1040 if (UserConfig)
1041 Config = *UserConfig;
1042
1044 if (Config.has(PassAddress))
1045 IRTArgs.push_back(IRTArg(IIRB.PtrTy, "address", "The function address.",
1047 if (Config.has(PassName))
1048 IRTArgs.push_back(IRTArg(IIRB.PtrTy, "name", "The function name.",
1050 if (Config.has(PassNumArguments))
1051 IRTArgs.push_back(
1052 IRTArg(IIRB.Int32Ty, "num_arguments",
1053 "Number of function arguments (without varargs).", IRTArg::NONE,
1054 std::bind(&FunctionIO::getNumArguments, this, _1, _2, _3, _4)));
1055 if (Config.has(PassArguments))
1056 IRTArgs.push_back(IRTArg(
1057 IIRB.PtrTy, "arguments", "Description of the arguments.",
1059 : IRTArg::NONE) |
1061 std::bind(&FunctionIO::getArguments, this, _1, _2, _3, _4),
1062 std::bind(&FunctionIO::setArguments, this, _1, _2, _3, _4)));
1063 if (Config.has(PassIsMain))
1064 IRTArgs.push_back(IRTArg(IIRB.Int8Ty, "is_main",
1065 "Flag to indicate it is the main function.",
1067 addCommonArgs(IConf, IIRB.Ctx, Config.has(PassId));
1068 IConf.addChoice(*this, IIRB.Ctx);
1069}
1070
1072 InstrumentationConfig &IConf,
1074 auto &Fn = cast<Function>(V);
1075 if (Fn.isIntrinsic())
1076 return Constant::getNullValue(&Ty);
1077 return &V;
1078}
1080 InstrumentationConfig &IConf,
1082 auto &Fn = cast<Function>(V);
1083 return IConf.getGlobalString(IConf.DemangleFunctionNames->getBool()
1084 ? demangle(Fn.getName())
1085 : Fn.getName(),
1086 IIRB);
1087}
1089 InstrumentationConfig &IConf,
1091 auto &Fn = cast<Function>(V);
1092 if (!Config.ArgFilter)
1093 return getCI(&Ty, Fn.arg_size());
1094 auto FRange = make_filter_range(Fn.args(), Config.ArgFilter);
1095 return getCI(&Ty, std::distance(FRange.begin(), FRange.end()));
1096}
1098 InstrumentationConfig &IConf,
1100 auto &Fn = cast<Function>(V);
1101 if (!Config.ArgFilter)
1102 return createValuePack(Fn.args(), IConf, IIRB);
1103 return createValuePack(make_filter_range(Fn.args(), Config.ArgFilter), IConf,
1104 IIRB);
1105}
1107 InstrumentationConfig &IConf,
1109 auto &Fn = cast<Function>(V);
1110 auto *AIt = Fn.arg_begin();
1111 auto CB = [&](int Idx, Value *ReplV) {
1112 while (Config.ArgFilter && !Config.ArgFilter(*AIt))
1113 ++AIt;
1114 Fn.getArg(Idx)->replaceUsesWithIf(ReplV, [&](Use &U) {
1115 return IIRB.NewInsts.lookup(cast<Instruction>(U.getUser())) != IIRB.Epoch;
1116 });
1117 ++AIt;
1118 };
1119 if (!Config.ArgFilter)
1120 readValuePack(Fn.args(), NewV, IIRB, CB);
1121 else
1122 readValuePack(make_filter_range(Fn.args(), Config.ArgFilter), NewV, IIRB,
1123 CB);
1124 return &Fn;
1125}
1127 InstrumentationConfig &IConf,
1129 auto &Fn = cast<Function>(V);
1130 return getCI(&Ty, Fn.getName() == "main");
1131}
1132
1133/// UnreachableIO
1134///{
1136 InstrumentorIRBuilderTy &IIRB, ConfigTy *UserConfig) {
1137 if (UserConfig)
1138 Config = *UserConfig;
1139 addCommonArgs(IConf, IIRB.Ctx, Config.has(PassId));
1140 IConf.addChoice(*this, IIRB.Ctx);
1141}
1142///}
1143
1144/// AllocaIO
1145///{
1147 ConfigTy *UserConfig) {
1148 if (UserConfig)
1149 Config = *UserConfig;
1150
1152 if (!IsPRE && Config.has(PassAddress))
1153 IRTArgs.push_back(
1154 IRTArg(IIRB.PtrTy, "address", "The allocated memory address.",
1158 if (Config.has(PassSize))
1159 IRTArgs.push_back(IRTArg(
1160 IIRB.Int64Ty, "size", "The allocation size.",
1162 getSize, setSize));
1163 if (Config.has(PassAlignment))
1164 IRTArgs.push_back(IRTArg(IIRB.Int64Ty, "alignment",
1165 "The allocation alignment.", IRTArg::NONE,
1166 getAlignment));
1167
1168 addCommonArgs(IConf, IIRB.Ctx, Config.has(PassId));
1169 IConf.addChoice(*this, IIRB.Ctx);
1170}
1171
1174 auto &AI = cast<AllocaInst>(V);
1175 const DataLayout &DL = AI.getDataLayout();
1176 Value *SizeValue = nullptr;
1177 TypeSize TypeSize = DL.getTypeAllocSize(AI.getAllocatedType());
1178 if (TypeSize.isFixed()) {
1179 SizeValue = getCI(&Ty, TypeSize.getFixedValue());
1180 } else {
1181 auto *NullPtr = ConstantPointerNull::get(AI.getType());
1182 SizeValue = IIRB.IRB.CreatePtrToInt(
1183 IIRB.IRB.CreateGEP(AI.getAllocatedType(), NullPtr,
1184 {IIRB.IRB.getInt32(1)}),
1185 &Ty);
1186 }
1187 if (AI.isArrayAllocation())
1188 SizeValue = IIRB.IRB.CreateMul(
1189 SizeValue, IIRB.IRB.CreateZExtOrBitCast(AI.getArraySize(), &Ty));
1190 return SizeValue;
1191}
1192
1195 auto &AI = cast<AllocaInst>(V);
1196 const DataLayout &DL = AI.getDataLayout();
1197 auto *NewAI = IIRB.IRB.CreateAlloca(IIRB.IRB.getInt8Ty(),
1198 DL.getAllocaAddrSpace(), &NewV);
1199 NewAI->setAlignment(AI.getAlign());
1200 AI.replaceAllUsesWith(NewAI);
1201 IIRB.eraseLater(&AI);
1202 return NewAI;
1203}
1204
1207 return getCI(&Ty, cast<AllocaInst>(V).getAlign().value());
1208}
1209///}
1210
1212 ConfigTy *UserConfig) {
1213 if (UserConfig)
1214 Config = *UserConfig;
1215
1217 if (Config.has(PassPointer)) {
1218 IRTArgs.push_back(
1219 IRTArg(IIRB.PtrTy, "pointer", "The accessed pointer.",
1220 ((IsPRE && Config.has(ReplacePointer)) ? IRTArg::REPLACABLE
1221 : IRTArg::NONE),
1223 }
1224 if (Config.has(PassPointerAS)) {
1225 IRTArgs.push_back(IRTArg(IIRB.Int32Ty, "pointer_as",
1226 "The address space of the accessed pointer.",
1228 }
1229 if (Config.has(PassBasePointerInfo)) {
1230 IRTArgs.push_back(IRTArg(IIRB.PtrTy, "base_pointer_info",
1231 "The runtime provided base pointer info.",
1233 }
1234 if (Config.has(PassStoredValue)) {
1235 IRTArgs.push_back(
1236 IRTArg(getValueType(IIRB), "value", "The stored value.",
1239 : IRTArg::NONE),
1240 getValue));
1241 }
1242 if (Config.has(PassStoredValueSize)) {
1243 IRTArgs.push_back(IRTArg(IIRB.Int64Ty, "value_size",
1244 "The size of the stored value.", IRTArg::NONE,
1245 getValueSize));
1246 }
1247 if (Config.has(PassAlignment)) {
1248 IRTArgs.push_back(IRTArg(IIRB.Int64Ty, "alignment",
1249 "The known access alignment.", IRTArg::NONE,
1250 getAlignment));
1251 }
1252 if (Config.has(PassValueTypeId)) {
1253 IRTArgs.push_back(IRTArg(IIRB.Int32Ty, "value_type_id",
1254 "The type id of the stored value.", IRTArg::TYPEID,
1256 }
1257 if (Config.has(PassValueSubTypeId)) {
1258 IRTArgs.push_back(IRTArg(
1259 IIRB.Int32Ty, "value_sub_type_id",
1260 "The type id of the stored value (for arrays and vectors, or -1).",
1262 }
1263 if (Config.has(PassAtomicityOrdering)) {
1264 IRTArgs.push_back(IRTArg(IIRB.Int32Ty, "atomicity_ordering",
1265 "The atomicity ordering of the store.",
1267 }
1268 if (Config.has(PassSyncScopeId)) {
1269 IRTArgs.push_back(IRTArg(IIRB.Int8Ty, "sync_scope_id",
1270 "The sync scope id of the store.", IRTArg::NONE,
1272 }
1273 if (Config.has(PassIsVolatile)) {
1274 IRTArgs.push_back(IRTArg(IIRB.Int8Ty, "is_volatile",
1275 "Flag indicating a volatile store.", IRTArg::NONE,
1276 isVolatile));
1277 }
1278
1279 addCommonArgs(IConf, IIRB.Ctx, Config.has(PassId));
1280 IConf.addChoice(*this, IIRB.Ctx);
1281}
1282
1285 auto &SI = cast<StoreInst>(V);
1286 return SI.getPointerOperand();
1287}
1288
1291 auto &SI = cast<StoreInst>(V);
1292 SI.setOperand(SI.getPointerOperandIndex(), &NewV);
1293 return &SI;
1294}
1295
1298 auto &SI = cast<StoreInst>(V);
1299 return getCI(&Ty, SI.getPointerAddressSpace());
1300}
1301
1303 InstrumentationConfig &IConf,
1305 auto &SI = cast<StoreInst>(V);
1306 return IConf.getBasePointerInfo(*SI.getPointerOperand(), IIRB);
1307}
1308
1311 auto &SI = cast<StoreInst>(V);
1312 return SI.getValueOperand();
1313}
1314
1317 auto &SI = cast<StoreInst>(V);
1318 auto &DL = SI.getDataLayout();
1319 return getCI(&Ty, DL.getTypeStoreSize(SI.getValueOperand()->getType()));
1320}
1321
1324 auto &SI = cast<StoreInst>(V);
1325 return getCI(&Ty, SI.getAlign().value());
1326}
1327
1330 auto &SI = cast<StoreInst>(V);
1331 return getCI(&Ty, SI.getValueOperand()->getType()->getTypeID());
1332}
1333
1335 InstrumentationConfig &IConf,
1337 auto &SI = cast<StoreInst>(V);
1338 return getSubTypeID(*SI.getValueOperand()->getType(), Ty);
1339}
1340
1342 InstrumentationConfig &IConf,
1344 auto &SI = cast<StoreInst>(V);
1345 return getCI(&Ty, uint64_t(SI.getOrdering()));
1346}
1347
1350 auto &SI = cast<StoreInst>(V);
1351 return getCI(&Ty, uint64_t(SI.getSyncScopeID()));
1352}
1353
1356 auto &SI = cast<StoreInst>(V);
1357 return getCI(&Ty, SI.isVolatile());
1358}
1359
1361 ConfigTy *UserConfig) {
1363 if (UserConfig)
1364 Config = *UserConfig;
1365 if (Config.has(PassPointer)) {
1366 IRTArgs.push_back(
1367 IRTArg(IIRB.PtrTy, "pointer", "The accessed pointer.",
1368 ((IsPRE && Config.has(ReplacePointer)) ? IRTArg::REPLACABLE
1369 : IRTArg::NONE),
1371 }
1372 if (Config.has(PassPointerAS)) {
1373 IRTArgs.push_back(IRTArg(IIRB.Int32Ty, "pointer_as",
1374 "The address space of the accessed pointer.",
1376 }
1377 if (Config.has(PassBasePointerInfo)) {
1378 IRTArgs.push_back(IRTArg(IIRB.PtrTy, "base_pointer_info",
1379 "The runtime provided base pointer info.",
1381 }
1382 if (!IsPRE && Config.has(PassValue)) {
1383 IRTArgs.push_back(
1384 IRTArg(getValueType(IIRB), "value", "The loaded value.",
1385 Config.has(ReplaceValue)
1388 : IRTArg::NONE)
1389 : IRTArg::NONE,
1390 getValue, Config.has(ReplaceValue) ? replaceValue : nullptr));
1391 }
1392 if (Config.has(PassValueSize)) {
1393 IRTArgs.push_back(IRTArg(IIRB.Int64Ty, "value_size",
1394 "The size of the loaded value.", IRTArg::NONE,
1395 getValueSize));
1396 }
1397 if (Config.has(PassAlignment)) {
1398 IRTArgs.push_back(IRTArg(IIRB.Int64Ty, "alignment",
1399 "The known access alignment.", IRTArg::NONE,
1400 getAlignment));
1401 }
1402 if (Config.has(PassValueTypeId)) {
1403 IRTArgs.push_back(IRTArg(IIRB.Int32Ty, "value_type_id",
1404 "The type id of the loaded value.", IRTArg::TYPEID,
1406 }
1407 if (Config.has(PassValueSubTypeId)) {
1408 IRTArgs.push_back(IRTArg(
1409 IIRB.Int32Ty, "value_sub_type_id",
1410 "The sub type id of the loaded value (for arrays and vectors, or -1).",
1412 }
1413 if (Config.has(PassAtomicityOrdering)) {
1414 IRTArgs.push_back(IRTArg(IIRB.Int32Ty, "atomicity_ordering",
1415 "The atomicity ordering of the load.",
1417 }
1418 if (Config.has(PassSyncScopeId)) {
1419 IRTArgs.push_back(IRTArg(IIRB.Int8Ty, "sync_scope_id",
1420 "The sync scope id of the load.", IRTArg::NONE,
1422 }
1423 if (Config.has(PassIsVolatile)) {
1424 IRTArgs.push_back(IRTArg(IIRB.Int8Ty, "is_volatile",
1425 "Flag indicating a volatile load.", IRTArg::NONE,
1426 isVolatile));
1427 }
1428
1429 addCommonArgs(IConf, IIRB.Ctx, Config.has(PassId));
1430 IConf.addChoice(*this, IIRB.Ctx);
1431}
1432
1435 auto &LI = cast<LoadInst>(V);
1436 return LI.getPointerOperand();
1437}
1438
1441 auto &LI = cast<LoadInst>(V);
1442 LI.setOperand(LI.getPointerOperandIndex(), &NewV);
1443 return &LI;
1444}
1445
1448 auto &LI = cast<LoadInst>(V);
1449 return getCI(&Ty, LI.getPointerAddressSpace());
1450}
1451
1453 InstrumentationConfig &IConf,
1455 auto &LI = cast<LoadInst>(V);
1456 return IConf.getBasePointerInfo(*LI.getPointerOperand(), IIRB);
1457}
1458
1461 return &V;
1462}
1463
1466 auto &LI = cast<LoadInst>(V);
1467 auto &DL = LI.getDataLayout();
1468 return getCI(&Ty, DL.getTypeStoreSize(LI.getType()));
1469}
1470
1473 auto &LI = cast<LoadInst>(V);
1474 return getCI(&Ty, LI.getAlign().value());
1475}
1476
1479 auto &LI = cast<LoadInst>(V);
1480 return getCI(&Ty, LI.getType()->getTypeID());
1481}
1482
1484 InstrumentationConfig &IConf,
1486 auto &LI = cast<LoadInst>(V);
1487 return getSubTypeID(*LI.getType(), Ty);
1488}
1489
1491 InstrumentationConfig &IConf,
1493 auto &LI = cast<LoadInst>(V);
1494 return getCI(&Ty, uint64_t(LI.getOrdering()));
1495}
1496
1499 auto &LI = cast<LoadInst>(V);
1500 return getCI(&Ty, uint64_t(LI.getSyncScopeID()));
1501}
1502
1505 auto &LI = cast<LoadInst>(V);
1506 return getCI(&Ty, LI.isVolatile());
1507}
1508
1510 InstrumentorIRBuilderTy &IIRB, ConfigTy *UserConfig) {
1511 if (UserConfig)
1512 Config = *UserConfig;
1513 if (Config.has(PassPointer))
1514 IRTArgs.push_back(IRTArg(IIRB.PtrTy, "base_pointer",
1515 "The base pointer in question.",
1517 if (Config.has(PassPointerKind))
1518 IRTArgs.push_back(IRTArg(
1519 IIRB.Int32Ty, "base_pointer_kind",
1520 "The base pointer kind (argument, global, instruction, unknown).",
1522 addCommonArgs(IConf, IIRB.Ctx, Config.has(PassId));
1523 IConf.addChoice(*this, IIRB.Ctx);
1524}
1525
1527 InstrumentationConfig &IConf,
1529 if (isa<Argument>(V))
1530 return getCI(&Ty, 0);
1531 if (isa<GlobalValue>(V))
1532 return getCI(&Ty, 1);
1533 if (isa<Instruction>(V))
1534 return getCI(&Ty, 2);
1535 return getCI(&Ty, 3);
1536}
1537
1539 ConfigTy *UserConfig) {
1540 if (UserConfig)
1541 Config = *UserConfig;
1542
1543 if (Config.has(PassName))
1544 IRTArgs.push_back(IRTArg(IIRB.PtrTy, "module_name",
1545 "The module/translation unit name.",
1547 if (Config.has(PassTargetTriple))
1548 IRTArgs.push_back(IRTArg(IIRB.PtrTy, "target_triple", "The target triple.",
1550
1551 addCommonArgs(IConf, IIRB.Ctx, Config.has(PassId));
1552 IConf.addChoice(*this, IIRB.Ctx);
1553}
1556 // V is a constructor or destructor of the module we can place code in.
1557 auto &Fn = cast<Function>(V);
1558 return IConf.getGlobalString(Fn.getParent()->getName(), IIRB);
1559}
1561 InstrumentationConfig &IConf,
1563 // V is a constructor or destructor of the module we can place code in.
1564 auto &Fn = cast<Function>(V);
1565 return IConf.getGlobalString(Fn.getParent()->getTargetTriple().getTriple(),
1566 IIRB);
1567}
1568
1570 InstrumentorIRBuilderTy &IIRB, ConfigTy *UserConfig) {
1571 if (UserConfig)
1572 Config = *UserConfig;
1574 if (Config.has(PassAddress))
1575 IRTArgs.push_back(IRTArg(
1576 IIRB.PtrTy, "address",
1577 "The address of the global (replaceable for definitions).",
1580 if (Config.has(PassAS))
1581 IRTArgs.push_back(IRTArg(IIRB.Int32Ty, "address_space",
1582 "The address space of the global.", IRTArg::NONE,
1583 getAS));
1584 if (Config.has(PassDeclaredSize))
1585 IRTArgs.push_back(IRTArg(IIRB.Int64Ty, "declared_size",
1586 "The size of the declared type of the global.",
1588 if (Config.has(PassAlignment))
1589 IRTArgs.push_back(IRTArg(IIRB.Int64Ty, "alignment",
1590 "The allocation alignment.", IRTArg::NONE,
1591 getAlignment));
1592 if (Config.has(PassName))
1593 IRTArgs.push_back(IRTArg(IIRB.PtrTy, "name", "The name of the global.",
1595 if (Config.has(PassInitialValue))
1596 IRTArgs.push_back(IRTArg(
1597 IIRB.Int64Ty, "initial_value", "The initial value of the global.",
1600 if (Config.has(PassIsConstant))
1601 IRTArgs.push_back(IRTArg(IIRB.Int8Ty, "is_constant",
1602 "Flag to indicate constant globals.", IRTArg::NONE,
1603 isConstant));
1604 if (Config.has(PassIsDefinition))
1605 IRTArgs.push_back(IRTArg(IIRB.Int8Ty, "is_definition",
1606 "Flag to indicate global definitions.",
1608 addCommonArgs(IConf, IIRB.Ctx, Config.has(PassId));
1609 IConf.addChoice(*this, IIRB.Ctx);
1610}
1614 if (GV.getAddressSpace())
1615 return ConstantExpr::getAddrSpaceCast(&GV, IIRB.PtrTy);
1616 return &GV;
1617}
1619 InstrumentationConfig &IConf,
1622
1623 GlobalVariable *ShadowGV = nullptr;
1624 auto ShadowName = IConf.getRTName("shadow.", GV.getName());
1625 auto &DL = GV.getDataLayout();
1626 if (GV.isDeclaration()) {
1627 ShadowGV = new GlobalVariable(*GV.getParent(), GV.getType(), false,
1629 ShadowName, &GV, GV.getThreadLocalMode(),
1630 DL.getDefaultGlobalsAddressSpace());
1631 } else {
1632 ShadowGV = new GlobalVariable(
1633 *GV.getParent(), NewV.getType(), false, GV.getLinkage(),
1634 PoisonValue::get(NewV.getType()), ShadowName, &GV);
1635 IIRB.IRB.CreateStore(&NewV, ShadowGV);
1636 }
1637
1641 DenseMap<Value *, Instruction *> ConstToInstMap;
1643
1644 auto MakeInstForConst = [&](Use &U) {
1645 Instruction *&I = ConstToInstMap[U];
1646 if (I)
1647 return;
1648 if (U == &GV) {
1649 } else if (auto *CE = dyn_cast<ConstantExpr>(U)) {
1650 I = CE->getAsInstruction();
1651 }
1652 };
1653
1654 auto InsertConsts = [&](Instruction *UserI, Use &UserU) {
1656 auto *&Reload = ReloadMap[UserI->getFunction()];
1657 if (!Reload) {
1658 Reload = new LoadInst(
1659 GV.getType(), ShadowGV, GV.getName() + ".shadow_load",
1661 IIRB.NewInsts.insert({Reload, IIRB.Epoch});
1662 }
1663 Worklist.push_back({UserI, &UserU});
1664 while (!Worklist.empty()) {
1665 auto [I, U] = Worklist.pop_back_val();
1666 if (*U == &GV) {
1667 U->set(ReloadMap[I->getFunction()]);
1668 continue;
1669 }
1670 if (auto *CI = ConstToInstMap[*U]) {
1671 auto *CIClone = CI->clone();
1672 IIRB.NewInsts.insert({CIClone, IIRB.Epoch});
1673 if (auto *PHI = dyn_cast<PHINode>(I)) {
1674 auto *BB = PHI->getIncomingBlock(U->getOperandNo());
1675 CIClone->insertBefore(BB->getTerminator()->getIterator());
1676 } else {
1677 CIClone->insertBefore(I->getIterator());
1678 }
1679 U->set(CIClone);
1680 for (auto &CICUse : CIClone->operands()) {
1681 Worklist.push_back({CIClone, &CICUse});
1682 }
1683 }
1684 }
1685 };
1686
1687 SmallPtrSet<Use *, 8> Visited;
1688 while (!Worklist.empty()) {
1689 Use *U = Worklist.pop_back_val();
1690 if (!Done.insert(U).second)
1691 continue;
1692 MakeInstForConst(*U);
1693 auto *I = dyn_cast<Instruction>(U->getUser());
1694 if (!I) {
1695 append_range(Worklist, make_pointer_range(U->getUser()->uses()));
1696 continue;
1697 }
1698 if (IIRB.NewInsts.lookup(I) == IIRB.Epoch)
1699 continue;
1701 continue;
1702 if (auto *II = dyn_cast<IntrinsicInst>(I))
1703 if (II->getIntrinsicID() == Intrinsic::eh_typeid_for)
1704 continue;
1705 if (I->getParent())
1706 InsertConsts(I, *U);
1707 }
1708
1709 for (auto &It : ConstToInstMap)
1710 if (It.second)
1711 It.second->deleteValue();
1712
1713 return &V;
1714}
1718 return getCI(&Ty, GV.getAddressSpace());
1719}
1721 InstrumentationConfig &IConf,
1724 return getCI(&Ty, GV.getAlignment());
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);
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);
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.
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:168
const BasicBlock & getEntryBlock() const
Definition Function.h:786
const DataLayout & getDataLayout() const
Get the data layout of the module this function belongs to.
Definition Function.cpp:357
iterator_range< arg_iterator > args()
Definition Function.h:869
arg_iterator arg_begin()
Definition Function.h:845
bool isIntrinsic() const
isIntrinsic - Returns true if the function's name starts with "llvm.".
Definition Function.h:251
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
Definition Function.cpp:353
size_t arg_size() const
Definition Function.h:878
Argument * getArg(unsigned i) const
Definition Function.h:863
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
Definition Function.cpp:727
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.
uint64_t getAlignment() const
FIXME: Remove this function once transition to Align is over.
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:67
const Triple & getTargetTriple() const
Get the target triple which is a string describing the target host.
Definition Module.h:323
LLVMContext & getContext() const
Get the global data context.
Definition Module.h:327
StringRef getName() const
Get a short "name" for the module.
Definition Module.h:311
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:579
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:578
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:95
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