106f32e7eSjoerg //===- Transforms/Instrumentation.h - Instrumentation passes ----*- C++ -*-===//
206f32e7eSjoerg //
306f32e7eSjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
406f32e7eSjoerg // See https://llvm.org/LICENSE.txt for license information.
506f32e7eSjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
606f32e7eSjoerg //
706f32e7eSjoerg //===----------------------------------------------------------------------===//
806f32e7eSjoerg //
906f32e7eSjoerg // This file defines constructor functions for instrumentation passes.
1006f32e7eSjoerg //
1106f32e7eSjoerg //===----------------------------------------------------------------------===//
1206f32e7eSjoerg 
1306f32e7eSjoerg #ifndef LLVM_TRANSFORMS_INSTRUMENTATION_H
1406f32e7eSjoerg #define LLVM_TRANSFORMS_INSTRUMENTATION_H
1506f32e7eSjoerg 
1606f32e7eSjoerg #include "llvm/ADT/StringRef.h"
1706f32e7eSjoerg #include "llvm/IR/BasicBlock.h"
1806f32e7eSjoerg #include <cassert>
1906f32e7eSjoerg #include <cstdint>
2006f32e7eSjoerg #include <limits>
2106f32e7eSjoerg #include <string>
2206f32e7eSjoerg #include <vector>
2306f32e7eSjoerg 
2406f32e7eSjoerg namespace llvm {
2506f32e7eSjoerg 
2606f32e7eSjoerg class Triple;
2706f32e7eSjoerg class FunctionPass;
2806f32e7eSjoerg class ModulePass;
2906f32e7eSjoerg class OptimizationRemarkEmitter;
3006f32e7eSjoerg class Comdat;
31*da58b97aSjoerg class CallBase;
3206f32e7eSjoerg 
3306f32e7eSjoerg /// Instrumentation passes often insert conditional checks into entry blocks.
3406f32e7eSjoerg /// Call this function before splitting the entry block to move instructions
3506f32e7eSjoerg /// that must remain in the entry block up before the split point. Static
3606f32e7eSjoerg /// allocas and llvm.localescape calls, for example, must remain in the entry
3706f32e7eSjoerg /// block.
3806f32e7eSjoerg BasicBlock::iterator PrepareToSplitEntryBlock(BasicBlock &BB,
3906f32e7eSjoerg                                               BasicBlock::iterator IP);
4006f32e7eSjoerg 
4106f32e7eSjoerg // Create a constant for Str so that we can pass it to the run-time lib.
4206f32e7eSjoerg GlobalVariable *createPrivateGlobalForString(Module &M, StringRef Str,
4306f32e7eSjoerg                                              bool AllowMerging,
4406f32e7eSjoerg                                              const char *NamePrefix = "");
4506f32e7eSjoerg 
4606f32e7eSjoerg // Returns F.getComdat() if it exists.
4706f32e7eSjoerg // Otherwise creates a new comdat, sets F's comdat, and returns it.
4806f32e7eSjoerg // Returns nullptr on failure.
49*da58b97aSjoerg Comdat *getOrCreateFunctionComdat(Function &F, Triple &T);
5006f32e7eSjoerg 
5106f32e7eSjoerg // Insert GCOV profiling instrumentation
5206f32e7eSjoerg struct GCOVOptions {
5306f32e7eSjoerg   static GCOVOptions getDefault();
5406f32e7eSjoerg 
5506f32e7eSjoerg   // Specify whether to emit .gcno files.
5606f32e7eSjoerg   bool EmitNotes;
5706f32e7eSjoerg 
5806f32e7eSjoerg   // Specify whether to modify the program to emit .gcda files when run.
5906f32e7eSjoerg   bool EmitData;
6006f32e7eSjoerg 
6106f32e7eSjoerg   // A four-byte version string. The meaning of a version string is described in
6206f32e7eSjoerg   // gcc's gcov-io.h
6306f32e7eSjoerg   char Version[4];
6406f32e7eSjoerg 
6506f32e7eSjoerg   // Add the 'noredzone' attribute to added runtime library calls.
6606f32e7eSjoerg   bool NoRedZone;
6706f32e7eSjoerg 
68*da58b97aSjoerg   // Use atomic profile counter increments.
69*da58b97aSjoerg   bool Atomic = false;
7006f32e7eSjoerg 
7106f32e7eSjoerg   // Regexes separated by a semi-colon to filter the files to instrument.
7206f32e7eSjoerg   std::string Filter;
7306f32e7eSjoerg 
7406f32e7eSjoerg   // Regexes separated by a semi-colon to filter the files to not instrument.
7506f32e7eSjoerg   std::string Exclude;
7606f32e7eSjoerg };
7706f32e7eSjoerg 
7806f32e7eSjoerg ModulePass *createGCOVProfilerPass(const GCOVOptions &Options =
7906f32e7eSjoerg                                    GCOVOptions::getDefault());
8006f32e7eSjoerg 
8106f32e7eSjoerg // PGO Instrumention. Parameter IsCS indicates if this is the context senstive
8206f32e7eSjoerg // instrumentation.
8306f32e7eSjoerg ModulePass *createPGOInstrumentationGenLegacyPass(bool IsCS = false);
8406f32e7eSjoerg ModulePass *
8506f32e7eSjoerg createPGOInstrumentationUseLegacyPass(StringRef Filename = StringRef(""),
8606f32e7eSjoerg                                       bool IsCS = false);
8706f32e7eSjoerg ModulePass *createPGOInstrumentationGenCreateVarLegacyPass(
8806f32e7eSjoerg     StringRef CSInstrName = StringRef(""));
8906f32e7eSjoerg ModulePass *createPGOIndirectCallPromotionLegacyPass(bool InLTO = false,
9006f32e7eSjoerg                                                      bool SamplePGO = false);
9106f32e7eSjoerg FunctionPass *createPGOMemOPSizeOptLegacyPass();
9206f32e7eSjoerg 
93*da58b97aSjoerg ModulePass *createCGProfileLegacyPass();
94*da58b97aSjoerg 
9506f32e7eSjoerg // The pgo-specific indirect call promotion function declared below is used by
9606f32e7eSjoerg // the pgo-driven indirect call promotion and sample profile passes. It's a
9706f32e7eSjoerg // wrapper around llvm::promoteCall, et al. that additionally computes !prof
9806f32e7eSjoerg // metadata. We place it in a pgo namespace so it's not confused with the
9906f32e7eSjoerg // generic utilities.
10006f32e7eSjoerg namespace pgo {
10106f32e7eSjoerg 
102*da58b97aSjoerg // Helper function that transforms CB (either an indirect-call instruction, or
10306f32e7eSjoerg // an invoke instruction , to a conditional call to F. This is like:
10406f32e7eSjoerg //     if (Inst.CalledValue == F)
10506f32e7eSjoerg //        F(...);
10606f32e7eSjoerg //     else
10706f32e7eSjoerg //        Inst(...);
10806f32e7eSjoerg //     end
10906f32e7eSjoerg // TotalCount is the profile count value that the instruction executes.
11006f32e7eSjoerg // Count is the profile count value that F is the target function.
11106f32e7eSjoerg // These two values are used to update the branch weight.
11206f32e7eSjoerg // If \p AttachProfToDirectCall is true, a prof metadata is attached to the
11306f32e7eSjoerg // new direct call to contain \p Count.
11406f32e7eSjoerg // Returns the promoted direct call instruction.
115*da58b97aSjoerg CallBase &promoteIndirectCall(CallBase &CB, Function *F, uint64_t Count,
116*da58b97aSjoerg                               uint64_t TotalCount, bool AttachProfToDirectCall,
11706f32e7eSjoerg                               OptimizationRemarkEmitter *ORE);
11806f32e7eSjoerg } // namespace pgo
11906f32e7eSjoerg 
12006f32e7eSjoerg /// Options for the frontend instrumentation based profiling pass.
12106f32e7eSjoerg struct InstrProfOptions {
12206f32e7eSjoerg   // Add the 'noredzone' attribute to added runtime library calls.
12306f32e7eSjoerg   bool NoRedZone = false;
12406f32e7eSjoerg 
12506f32e7eSjoerg   // Do counter register promotion
12606f32e7eSjoerg   bool DoCounterPromotion = false;
12706f32e7eSjoerg 
12806f32e7eSjoerg   // Use atomic profile counter increments.
12906f32e7eSjoerg   bool Atomic = false;
13006f32e7eSjoerg 
13106f32e7eSjoerg   // Use BFI to guide register promotion
13206f32e7eSjoerg   bool UseBFIInPromotion = false;
13306f32e7eSjoerg 
13406f32e7eSjoerg   // Name of the profile file to use as output
13506f32e7eSjoerg   std::string InstrProfileOutput;
13606f32e7eSjoerg 
13706f32e7eSjoerg   InstrProfOptions() = default;
13806f32e7eSjoerg };
13906f32e7eSjoerg 
14006f32e7eSjoerg /// Insert frontend instrumentation based profiling. Parameter IsCS indicates if
14106f32e7eSjoerg // this is the context senstive instrumentation.
14206f32e7eSjoerg ModulePass *createInstrProfilingLegacyPass(
14306f32e7eSjoerg     const InstrProfOptions &Options = InstrProfOptions(), bool IsCS = false);
14406f32e7eSjoerg 
14506f32e7eSjoerg ModulePass *createInstrOrderFilePass();
14606f32e7eSjoerg 
14706f32e7eSjoerg // Insert DataFlowSanitizer (dynamic data flow analysis) instrumentation
148*da58b97aSjoerg ModulePass *createDataFlowSanitizerLegacyPassPass(
149*da58b97aSjoerg     const std::vector<std::string> &ABIListFiles = std::vector<std::string>());
15006f32e7eSjoerg 
15106f32e7eSjoerg // Options for sanitizer coverage instrumentation.
15206f32e7eSjoerg struct SanitizerCoverageOptions {
15306f32e7eSjoerg   enum Type {
15406f32e7eSjoerg     SCK_None = 0,
15506f32e7eSjoerg     SCK_Function,
15606f32e7eSjoerg     SCK_BB,
15706f32e7eSjoerg     SCK_Edge
15806f32e7eSjoerg   } CoverageType = SCK_None;
15906f32e7eSjoerg   bool IndirectCalls = false;
16006f32e7eSjoerg   bool TraceBB = false;
16106f32e7eSjoerg   bool TraceCmp = false;
16206f32e7eSjoerg   bool TraceDiv = false;
16306f32e7eSjoerg   bool TraceGep = false;
16406f32e7eSjoerg   bool Use8bitCounters = false;
16506f32e7eSjoerg   bool TracePC = false;
16606f32e7eSjoerg   bool TracePCGuard = false;
16706f32e7eSjoerg   bool Inline8bitCounters = false;
168*da58b97aSjoerg   bool InlineBoolFlag = false;
16906f32e7eSjoerg   bool PCTable = false;
17006f32e7eSjoerg   bool NoPrune = false;
17106f32e7eSjoerg   bool StackDepth = false;
17206f32e7eSjoerg 
17306f32e7eSjoerg   SanitizerCoverageOptions() = default;
17406f32e7eSjoerg };
17506f32e7eSjoerg 
17606f32e7eSjoerg /// Calculate what to divide by to scale counts.
17706f32e7eSjoerg ///
17806f32e7eSjoerg /// Given the maximum count, calculate a divisor that will scale all the
17906f32e7eSjoerg /// weights to strictly less than std::numeric_limits<uint32_t>::max().
calculateCountScale(uint64_t MaxCount)18006f32e7eSjoerg static inline uint64_t calculateCountScale(uint64_t MaxCount) {
18106f32e7eSjoerg   return MaxCount < std::numeric_limits<uint32_t>::max()
18206f32e7eSjoerg              ? 1
18306f32e7eSjoerg              : MaxCount / std::numeric_limits<uint32_t>::max() + 1;
18406f32e7eSjoerg }
18506f32e7eSjoerg 
18606f32e7eSjoerg /// Scale an individual branch count.
18706f32e7eSjoerg ///
18806f32e7eSjoerg /// Scale a 64-bit weight down to 32-bits using \c Scale.
18906f32e7eSjoerg ///
scaleBranchCount(uint64_t Count,uint64_t Scale)19006f32e7eSjoerg static inline uint32_t scaleBranchCount(uint64_t Count, uint64_t Scale) {
19106f32e7eSjoerg   uint64_t Scaled = Count / Scale;
19206f32e7eSjoerg   assert(Scaled <= std::numeric_limits<uint32_t>::max() && "overflow 32-bits");
19306f32e7eSjoerg   return Scaled;
19406f32e7eSjoerg }
19506f32e7eSjoerg } // end namespace llvm
19606f32e7eSjoerg 
19706f32e7eSjoerg #endif // LLVM_TRANSFORMS_INSTRUMENTATION_H
198