10b57cec5SDimitry Andric //===- Transforms/Instrumentation.h - Instrumentation passes ----*- C++ -*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This file defines constructor functions for instrumentation passes. 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #ifndef LLVM_TRANSFORMS_INSTRUMENTATION_H 140b57cec5SDimitry Andric #define LLVM_TRANSFORMS_INSTRUMENTATION_H 150b57cec5SDimitry Andric 160b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h" 170b57cec5SDimitry Andric #include "llvm/IR/BasicBlock.h" 1881ad6265SDimitry Andric #include "llvm/IR/DebugInfoMetadata.h" 1981ad6265SDimitry Andric #include "llvm/IR/Function.h" 2081ad6265SDimitry Andric #include "llvm/IR/IRBuilder.h" 2181ad6265SDimitry Andric #include "llvm/IR/Instruction.h" 220b57cec5SDimitry Andric #include <cassert> 230b57cec5SDimitry Andric #include <cstdint> 240b57cec5SDimitry Andric #include <limits> 250b57cec5SDimitry Andric #include <string> 260b57cec5SDimitry Andric 270b57cec5SDimitry Andric namespace llvm { 280b57cec5SDimitry Andric 290b57cec5SDimitry Andric class Triple; 300b57cec5SDimitry Andric class OptimizationRemarkEmitter; 310b57cec5SDimitry Andric class Comdat; 325ffd83dbSDimitry Andric class CallBase; 330b57cec5SDimitry Andric 340b57cec5SDimitry Andric /// Instrumentation passes often insert conditional checks into entry blocks. 350b57cec5SDimitry Andric /// Call this function before splitting the entry block to move instructions 360b57cec5SDimitry Andric /// that must remain in the entry block up before the split point. Static 370b57cec5SDimitry Andric /// allocas and llvm.localescape calls, for example, must remain in the entry 380b57cec5SDimitry Andric /// block. 390b57cec5SDimitry Andric BasicBlock::iterator PrepareToSplitEntryBlock(BasicBlock &BB, 400b57cec5SDimitry Andric BasicBlock::iterator IP); 410b57cec5SDimitry Andric 420b57cec5SDimitry Andric // Create a constant for Str so that we can pass it to the run-time lib. 430b57cec5SDimitry Andric GlobalVariable *createPrivateGlobalForString(Module &M, StringRef Str, 440b57cec5SDimitry Andric bool AllowMerging, 450b57cec5SDimitry Andric const char *NamePrefix = ""); 460b57cec5SDimitry Andric 470b57cec5SDimitry Andric // Returns F.getComdat() if it exists. 480b57cec5SDimitry Andric // Otherwise creates a new comdat, sets F's comdat, and returns it. 490b57cec5SDimitry Andric // Returns nullptr on failure. 50fe6060f1SDimitry Andric Comdat *getOrCreateFunctionComdat(Function &F, Triple &T); 510b57cec5SDimitry Andric 525f757f3fSDimitry Andric // Place global in a large section for x86-64 ELF binaries to mitigate 535f757f3fSDimitry Andric // relocation overflow pressure. This can be be used for metadata globals that 545f757f3fSDimitry Andric // aren't directly accessed by code, which has no performance impact. 555f757f3fSDimitry Andric void setGlobalVariableLargeSection(const Triple &TargetTriple, 565f757f3fSDimitry Andric GlobalVariable &GV); 575f757f3fSDimitry Andric 580b57cec5SDimitry Andric // Insert GCOV profiling instrumentation 590b57cec5SDimitry Andric struct GCOVOptions { 600b57cec5SDimitry Andric static GCOVOptions getDefault(); 610b57cec5SDimitry Andric 620b57cec5SDimitry Andric // Specify whether to emit .gcno files. 630b57cec5SDimitry Andric bool EmitNotes; 640b57cec5SDimitry Andric 650b57cec5SDimitry Andric // Specify whether to modify the program to emit .gcda files when run. 660b57cec5SDimitry Andric bool EmitData; 670b57cec5SDimitry Andric 680b57cec5SDimitry Andric // A four-byte version string. The meaning of a version string is described in 690b57cec5SDimitry Andric // gcc's gcov-io.h 700b57cec5SDimitry Andric char Version[4]; 710b57cec5SDimitry Andric 720b57cec5SDimitry Andric // Add the 'noredzone' attribute to added runtime library calls. 730b57cec5SDimitry Andric bool NoRedZone; 740b57cec5SDimitry Andric 75e8d8bef9SDimitry Andric // Use atomic profile counter increments. 76e8d8bef9SDimitry Andric bool Atomic = false; 77e8d8bef9SDimitry Andric 780b57cec5SDimitry Andric // Regexes separated by a semi-colon to filter the files to instrument. 790b57cec5SDimitry Andric std::string Filter; 800b57cec5SDimitry Andric 810b57cec5SDimitry Andric // Regexes separated by a semi-colon to filter the files to not instrument. 820b57cec5SDimitry Andric std::string Exclude; 830b57cec5SDimitry Andric }; 840b57cec5SDimitry Andric 850b57cec5SDimitry Andric // The pgo-specific indirect call promotion function declared below is used by 860b57cec5SDimitry Andric // the pgo-driven indirect call promotion and sample profile passes. It's a 870b57cec5SDimitry Andric // wrapper around llvm::promoteCall, et al. that additionally computes !prof 880b57cec5SDimitry Andric // metadata. We place it in a pgo namespace so it's not confused with the 890b57cec5SDimitry Andric // generic utilities. 900b57cec5SDimitry Andric namespace pgo { 910b57cec5SDimitry Andric 925ffd83dbSDimitry Andric // Helper function that transforms CB (either an indirect-call instruction, or 930b57cec5SDimitry Andric // an invoke instruction , to a conditional call to F. This is like: 940b57cec5SDimitry Andric // if (Inst.CalledValue == F) 950b57cec5SDimitry Andric // F(...); 960b57cec5SDimitry Andric // else 970b57cec5SDimitry Andric // Inst(...); 980b57cec5SDimitry Andric // end 990b57cec5SDimitry Andric // TotalCount is the profile count value that the instruction executes. 1000b57cec5SDimitry Andric // Count is the profile count value that F is the target function. 1010b57cec5SDimitry Andric // These two values are used to update the branch weight. 1020b57cec5SDimitry Andric // If \p AttachProfToDirectCall is true, a prof metadata is attached to the 1030b57cec5SDimitry Andric // new direct call to contain \p Count. 1040b57cec5SDimitry Andric // Returns the promoted direct call instruction. 1055ffd83dbSDimitry Andric CallBase &promoteIndirectCall(CallBase &CB, Function *F, uint64_t Count, 1065ffd83dbSDimitry Andric uint64_t TotalCount, bool AttachProfToDirectCall, 1070b57cec5SDimitry Andric OptimizationRemarkEmitter *ORE); 1080b57cec5SDimitry Andric } // namespace pgo 1090b57cec5SDimitry Andric 1100b57cec5SDimitry Andric /// Options for the frontend instrumentation based profiling pass. 1110b57cec5SDimitry Andric struct InstrProfOptions { 1120b57cec5SDimitry Andric // Add the 'noredzone' attribute to added runtime library calls. 1130b57cec5SDimitry Andric bool NoRedZone = false; 1140b57cec5SDimitry Andric 1150b57cec5SDimitry Andric // Do counter register promotion 1160b57cec5SDimitry Andric bool DoCounterPromotion = false; 1170b57cec5SDimitry Andric 1180b57cec5SDimitry Andric // Use atomic profile counter increments. 1190b57cec5SDimitry Andric bool Atomic = false; 1200b57cec5SDimitry Andric 1210b57cec5SDimitry Andric // Use BFI to guide register promotion 1220b57cec5SDimitry Andric bool UseBFIInPromotion = false; 1230b57cec5SDimitry Andric 124*0fca6ea1SDimitry Andric // Use sampling to reduce the profile instrumentation runtime overhead. 125*0fca6ea1SDimitry Andric bool Sampling = false; 126*0fca6ea1SDimitry Andric 1270b57cec5SDimitry Andric // Name of the profile file to use as output 1280b57cec5SDimitry Andric std::string InstrProfileOutput; 1290b57cec5SDimitry Andric 1300b57cec5SDimitry Andric InstrProfOptions() = default; 1310b57cec5SDimitry Andric }; 1320b57cec5SDimitry Andric 133*0fca6ea1SDimitry Andric // Create the variable for profile sampling. 134*0fca6ea1SDimitry Andric void createProfileSamplingVar(Module &M); 135*0fca6ea1SDimitry Andric 1360b57cec5SDimitry Andric // Options for sanitizer coverage instrumentation. 1370b57cec5SDimitry Andric struct SanitizerCoverageOptions { 1380b57cec5SDimitry Andric enum Type { 1390b57cec5SDimitry Andric SCK_None = 0, 1400b57cec5SDimitry Andric SCK_Function, 1410b57cec5SDimitry Andric SCK_BB, 1420b57cec5SDimitry Andric SCK_Edge 1430b57cec5SDimitry Andric } CoverageType = SCK_None; 1440b57cec5SDimitry Andric bool IndirectCalls = false; 1450b57cec5SDimitry Andric bool TraceBB = false; 1460b57cec5SDimitry Andric bool TraceCmp = false; 1470b57cec5SDimitry Andric bool TraceDiv = false; 1480b57cec5SDimitry Andric bool TraceGep = false; 1490b57cec5SDimitry Andric bool Use8bitCounters = false; 1500b57cec5SDimitry Andric bool TracePC = false; 1510b57cec5SDimitry Andric bool TracePCGuard = false; 1520b57cec5SDimitry Andric bool Inline8bitCounters = false; 1535ffd83dbSDimitry Andric bool InlineBoolFlag = false; 1540b57cec5SDimitry Andric bool PCTable = false; 1550b57cec5SDimitry Andric bool NoPrune = false; 1560b57cec5SDimitry Andric bool StackDepth = false; 157349cc55cSDimitry Andric bool TraceLoads = false; 158349cc55cSDimitry Andric bool TraceStores = false; 159bdd1243dSDimitry Andric bool CollectControlFlow = false; 1600b57cec5SDimitry Andric 1610b57cec5SDimitry Andric SanitizerCoverageOptions() = default; 1620b57cec5SDimitry Andric }; 1630b57cec5SDimitry Andric 1640b57cec5SDimitry Andric /// Calculate what to divide by to scale counts. 1650b57cec5SDimitry Andric /// 1660b57cec5SDimitry Andric /// Given the maximum count, calculate a divisor that will scale all the 1670b57cec5SDimitry Andric /// weights to strictly less than std::numeric_limits<uint32_t>::max(). 1680b57cec5SDimitry Andric static inline uint64_t calculateCountScale(uint64_t MaxCount) { 1690b57cec5SDimitry Andric return MaxCount < std::numeric_limits<uint32_t>::max() 1700b57cec5SDimitry Andric ? 1 1710b57cec5SDimitry Andric : MaxCount / std::numeric_limits<uint32_t>::max() + 1; 1720b57cec5SDimitry Andric } 1730b57cec5SDimitry Andric 1740b57cec5SDimitry Andric /// Scale an individual branch count. 1750b57cec5SDimitry Andric /// 1760b57cec5SDimitry Andric /// Scale a 64-bit weight down to 32-bits using \c Scale. 1770b57cec5SDimitry Andric /// 1780b57cec5SDimitry Andric static inline uint32_t scaleBranchCount(uint64_t Count, uint64_t Scale) { 1790b57cec5SDimitry Andric uint64_t Scaled = Count / Scale; 1800b57cec5SDimitry Andric assert(Scaled <= std::numeric_limits<uint32_t>::max() && "overflow 32-bits"); 1810b57cec5SDimitry Andric return Scaled; 1820b57cec5SDimitry Andric } 18381ad6265SDimitry Andric 18481ad6265SDimitry Andric // Use to ensure the inserted instrumentation has a DebugLocation; if none is 18581ad6265SDimitry Andric // attached to the source instruction, try to use a DILocation with offset 0 18681ad6265SDimitry Andric // scoped to surrounding function (if it has a DebugLocation). 18781ad6265SDimitry Andric // 18881ad6265SDimitry Andric // Some non-call instructions may be missing debug info, but when inserting 18981ad6265SDimitry Andric // instrumentation calls, some builds (e.g. LTO) want calls to have debug info 19081ad6265SDimitry Andric // if the enclosing function does. 19181ad6265SDimitry Andric struct InstrumentationIRBuilder : IRBuilder<> { 19281ad6265SDimitry Andric static void ensureDebugInfo(IRBuilder<> &IRB, const Function &F) { 19381ad6265SDimitry Andric if (IRB.getCurrentDebugLocation()) 19481ad6265SDimitry Andric return; 19581ad6265SDimitry Andric if (DISubprogram *SP = F.getSubprogram()) 19681ad6265SDimitry Andric IRB.SetCurrentDebugLocation(DILocation::get(SP->getContext(), 0, 0, SP)); 19781ad6265SDimitry Andric } 19881ad6265SDimitry Andric 19981ad6265SDimitry Andric explicit InstrumentationIRBuilder(Instruction *IP) : IRBuilder<>(IP) { 20081ad6265SDimitry Andric ensureDebugInfo(*this, *IP->getFunction()); 20181ad6265SDimitry Andric } 20281ad6265SDimitry Andric }; 2030b57cec5SDimitry Andric } // end namespace llvm 2040b57cec5SDimitry Andric 2050b57cec5SDimitry Andric #endif // LLVM_TRANSFORMS_INSTRUMENTATION_H 206