Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:44:43

0001 //===- Transforms/Instrumentation.h - Instrumentation passes ----*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 // This file defines constructor functions for instrumentation passes.
0010 //
0011 //===----------------------------------------------------------------------===//
0012 
0013 #ifndef LLVM_TRANSFORMS_INSTRUMENTATION_H
0014 #define LLVM_TRANSFORMS_INSTRUMENTATION_H
0015 
0016 #include "llvm/ADT/StringRef.h"
0017 #include "llvm/IR/BasicBlock.h"
0018 #include "llvm/IR/DebugInfoMetadata.h"
0019 #include "llvm/IR/Function.h"
0020 #include "llvm/IR/IRBuilder.h"
0021 #include "llvm/IR/Instruction.h"
0022 #include <cassert>
0023 #include <cstdint>
0024 #include <limits>
0025 #include <string>
0026 
0027 namespace llvm {
0028 
0029 class Triple;
0030 class OptimizationRemarkEmitter;
0031 class Comdat;
0032 class CallBase;
0033 class Module;
0034 
0035 /// Check if module has flag attached, if not add the flag.
0036 bool checkIfAlreadyInstrumented(Module &M, StringRef Flag);
0037 
0038 /// Instrumentation passes often insert conditional checks into entry blocks.
0039 /// Call this function before splitting the entry block to move instructions
0040 /// that must remain in the entry block up before the split point. Static
0041 /// allocas and llvm.localescape calls, for example, must remain in the entry
0042 /// block.
0043 BasicBlock::iterator PrepareToSplitEntryBlock(BasicBlock &BB,
0044                                               BasicBlock::iterator IP);
0045 
0046 // Create a constant for Str so that we can pass it to the run-time lib.
0047 GlobalVariable *createPrivateGlobalForString(Module &M, StringRef Str,
0048                                              bool AllowMerging,
0049                                              Twine NamePrefix = "");
0050 
0051 // Returns F.getComdat() if it exists.
0052 // Otherwise creates a new comdat, sets F's comdat, and returns it.
0053 // Returns nullptr on failure.
0054 Comdat *getOrCreateFunctionComdat(Function &F, Triple &T);
0055 
0056 // Place global in a large section for x86-64 ELF binaries to mitigate
0057 // relocation overflow pressure. This can be be used for metadata globals that
0058 // aren't directly accessed by code, which has no performance impact.
0059 void setGlobalVariableLargeSection(const Triple &TargetTriple,
0060                                    GlobalVariable &GV);
0061 
0062 // Insert GCOV profiling instrumentation
0063 struct GCOVOptions {
0064   static GCOVOptions getDefault();
0065 
0066   // Specify whether to emit .gcno files.
0067   bool EmitNotes;
0068 
0069   // Specify whether to modify the program to emit .gcda files when run.
0070   bool EmitData;
0071 
0072   // A four-byte version string. The meaning of a version string is described in
0073   // gcc's gcov-io.h
0074   char Version[4];
0075 
0076   // Add the 'noredzone' attribute to added runtime library calls.
0077   bool NoRedZone;
0078 
0079   // Use atomic profile counter increments.
0080   bool Atomic = false;
0081 
0082   // Regexes separated by a semi-colon to filter the files to instrument.
0083   std::string Filter;
0084 
0085   // Regexes separated by a semi-colon to filter the files to not instrument.
0086   std::string Exclude;
0087 };
0088 
0089 // The pgo-specific indirect call promotion function declared below is used by
0090 // the pgo-driven indirect call promotion and sample profile passes. It's a
0091 // wrapper around llvm::promoteCall, et al. that additionally computes !prof
0092 // metadata. We place it in a pgo namespace so it's not confused with the
0093 // generic utilities.
0094 namespace pgo {
0095 
0096 // Helper function that transforms CB (either an indirect-call instruction, or
0097 // an invoke instruction , to a conditional call to F. This is like:
0098 //     if (Inst.CalledValue == F)
0099 //        F(...);
0100 //     else
0101 //        Inst(...);
0102 //     end
0103 // TotalCount is the profile count value that the instruction executes.
0104 // Count is the profile count value that F is the target function.
0105 // These two values are used to update the branch weight.
0106 // If \p AttachProfToDirectCall is true, a prof metadata is attached to the
0107 // new direct call to contain \p Count.
0108 // Returns the promoted direct call instruction.
0109 CallBase &promoteIndirectCall(CallBase &CB, Function *F, uint64_t Count,
0110                               uint64_t TotalCount, bool AttachProfToDirectCall,
0111                               OptimizationRemarkEmitter *ORE);
0112 } // namespace pgo
0113 
0114 /// Options for the frontend instrumentation based profiling pass.
0115 struct InstrProfOptions {
0116   // Add the 'noredzone' attribute to added runtime library calls.
0117   bool NoRedZone = false;
0118 
0119   // Do counter register promotion
0120   bool DoCounterPromotion = false;
0121 
0122   // Use atomic profile counter increments.
0123   bool Atomic = false;
0124 
0125   // Use BFI to guide register promotion
0126   bool UseBFIInPromotion = false;
0127 
0128   // Use sampling to reduce the profile instrumentation runtime overhead.
0129   bool Sampling = false;
0130 
0131   // Name of the profile file to use as output
0132   std::string InstrProfileOutput;
0133 
0134   InstrProfOptions() = default;
0135 };
0136 
0137 // Create the variable for profile sampling.
0138 void createProfileSamplingVar(Module &M);
0139 
0140 // Options for sanitizer coverage instrumentation.
0141 struct SanitizerCoverageOptions {
0142   enum Type {
0143     SCK_None = 0,
0144     SCK_Function,
0145     SCK_BB,
0146     SCK_Edge
0147   } CoverageType = SCK_None;
0148   bool IndirectCalls = false;
0149   bool TraceBB = false;
0150   bool TraceCmp = false;
0151   bool TraceDiv = false;
0152   bool TraceGep = false;
0153   bool Use8bitCounters = false;
0154   bool TracePC = false;
0155   bool TracePCGuard = false;
0156   bool Inline8bitCounters = false;
0157   bool InlineBoolFlag = false;
0158   bool PCTable = false;
0159   bool NoPrune = false;
0160   bool StackDepth = false;
0161   bool TraceLoads = false;
0162   bool TraceStores = false;
0163   bool CollectControlFlow = false;
0164   bool GatedCallbacks = false;
0165 
0166   SanitizerCoverageOptions() = default;
0167 };
0168 
0169 /// Calculate what to divide by to scale counts.
0170 ///
0171 /// Given the maximum count, calculate a divisor that will scale all the
0172 /// weights to strictly less than std::numeric_limits<uint32_t>::max().
0173 static inline uint64_t calculateCountScale(uint64_t MaxCount) {
0174   return MaxCount < std::numeric_limits<uint32_t>::max()
0175              ? 1
0176              : MaxCount / std::numeric_limits<uint32_t>::max() + 1;
0177 }
0178 
0179 /// Scale an individual branch count.
0180 ///
0181 /// Scale a 64-bit weight down to 32-bits using \c Scale.
0182 ///
0183 static inline uint32_t scaleBranchCount(uint64_t Count, uint64_t Scale) {
0184   uint64_t Scaled = Count / Scale;
0185   assert(Scaled <= std::numeric_limits<uint32_t>::max() && "overflow 32-bits");
0186   return Scaled;
0187 }
0188 
0189 // Use to ensure the inserted instrumentation has a DebugLocation; if none is
0190 // attached to the source instruction, try to use a DILocation with offset 0
0191 // scoped to surrounding function (if it has a DebugLocation).
0192 //
0193 // Some non-call instructions may be missing debug info, but when inserting
0194 // instrumentation calls, some builds (e.g. LTO) want calls to have debug info
0195 // if the enclosing function does.
0196 struct InstrumentationIRBuilder : IRBuilder<> {
0197   static void ensureDebugInfo(IRBuilder<> &IRB, const Function &F) {
0198     if (IRB.getCurrentDebugLocation())
0199       return;
0200     if (DISubprogram *SP = F.getSubprogram())
0201       IRB.SetCurrentDebugLocation(DILocation::get(SP->getContext(), 0, 0, SP));
0202   }
0203 
0204   explicit InstrumentationIRBuilder(Instruction *IP) : IRBuilder<>(IP) {
0205     ensureDebugInfo(*this, *IP->getFunction());
0206   }
0207 
0208   explicit InstrumentationIRBuilder(BasicBlock *BB, BasicBlock::iterator It)
0209       : IRBuilder<>(BB, It) {
0210     ensureDebugInfo(*this, *BB->getParent());
0211   }
0212 };
0213 } // end namespace llvm
0214 
0215 #endif // LLVM_TRANSFORMS_INSTRUMENTATION_H