Skip to content

[NFC][InstrProf] Move InstrProfiling to the .cpp file #75018

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Dec 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
157 changes: 0 additions & 157 deletions llvm/include/llvm/Transforms/Instrumentation/InstrProfiling.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,12 @@
#ifndef LLVM_TRANSFORMS_INSTRUMENTATION_INSTRPROFILING_H
#define LLVM_TRANSFORMS_INSTRUMENTATION_INSTRPROFILING_H

#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/PassManager.h"
#include "llvm/ProfileData/InstrProf.h"
#include "llvm/Transforms/Instrumentation.h"
#include <cstdint>
#include <cstring>
#include <vector>

namespace llvm {

class TargetLibraryInfo;
using LoadStorePair = std::pair<Instruction *, Instruction *>;

/// Instrumentation based profiling lowering pass. This pass lowers
/// the profile instrumented code generated by FE or the IR based
/// instrumentation pass.
Expand All @@ -44,154 +35,6 @@ class InstrProfilingLoweringPass

PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
};

class InstrProfiling final {
public:
InstrProfiling(Module &M, const InstrProfOptions &Options,
std::function<const TargetLibraryInfo &(Function &F)> GetTLI,
bool IsCS)
: M(M), Options(Options), TT(Triple(M.getTargetTriple())), IsCS(IsCS),
GetTLI(GetTLI) {}

bool lower();

private:
Module &M;
const InstrProfOptions Options;
const Triple TT;
// Is this lowering for the context-sensitive instrumentation.
const bool IsCS;

std::function<const TargetLibraryInfo &(Function &F)> GetTLI;
struct PerFunctionProfileData {
uint32_t NumValueSites[IPVK_Last + 1] = {};
GlobalVariable *RegionCounters = nullptr;
GlobalVariable *DataVar = nullptr;
GlobalVariable *RegionBitmaps = nullptr;
uint32_t NumBitmapBytes = 0;

PerFunctionProfileData() = default;
};
DenseMap<GlobalVariable *, PerFunctionProfileData> ProfileDataMap;
/// If runtime relocation is enabled, this maps functions to the load
/// instruction that produces the profile relocation bias.
DenseMap<const Function *, LoadInst *> FunctionToProfileBiasMap;
std::vector<GlobalValue *> CompilerUsedVars;
std::vector<GlobalValue *> UsedVars;
std::vector<GlobalVariable *> ReferencedNames;
GlobalVariable *NamesVar = nullptr;
size_t NamesSize = 0;

// vector of counter load/store pairs to be register promoted.
std::vector<LoadStorePair> PromotionCandidates;

int64_t TotalCountersPromoted = 0;

/// Lower instrumentation intrinsics in the function. Returns true if there
/// any lowering.
bool lowerIntrinsics(Function *F);

/// Register-promote counter loads and stores in loops.
void promoteCounterLoadStores(Function *F);

/// Returns true if relocating counters at runtime is enabled.
bool isRuntimeCounterRelocationEnabled() const;

/// Returns true if profile counter update register promotion is enabled.
bool isCounterPromotionEnabled() const;

/// Count the number of instrumented value sites for the function.
void computeNumValueSiteCounts(InstrProfValueProfileInst *Ins);

/// Replace instrprof.value.profile with a call to runtime library.
void lowerValueProfileInst(InstrProfValueProfileInst *Ins);

/// Replace instrprof.cover with a store instruction to the coverage byte.
void lowerCover(InstrProfCoverInst *Inc);

/// Replace instrprof.timestamp with a call to
/// INSTR_PROF_PROFILE_SET_TIMESTAMP.
void lowerTimestamp(InstrProfTimestampInst *TimestampInstruction);

/// Replace instrprof.increment with an increment of the appropriate value.
void lowerIncrement(InstrProfIncrementInst *Inc);

/// Force emitting of name vars for unused functions.
void lowerCoverageData(GlobalVariable *CoverageNamesVar);

/// Replace instrprof.mcdc.tvbitmask.update with a shift and or instruction
/// using the index represented by the a temp value into a bitmap.
void lowerMCDCTestVectorBitmapUpdate(InstrProfMCDCTVBitmapUpdate *Ins);

/// Replace instrprof.mcdc.temp.update with a shift and or instruction using
/// the corresponding condition ID.
void lowerMCDCCondBitmapUpdate(InstrProfMCDCCondBitmapUpdate *Ins);

/// Compute the address of the counter value that this profiling instruction
/// acts on.
Value *getCounterAddress(InstrProfCntrInstBase *I);

/// Get the region counters for an increment, creating them if necessary.
///
/// If the counter array doesn't yet exist, the profile data variables
/// referring to them will also be created.
GlobalVariable *getOrCreateRegionCounters(InstrProfCntrInstBase *Inc);

/// Create the region counters.
GlobalVariable *createRegionCounters(InstrProfCntrInstBase *Inc,
StringRef Name,
GlobalValue::LinkageTypes Linkage);

/// Compute the address of the test vector bitmap that this profiling
/// instruction acts on.
Value *getBitmapAddress(InstrProfMCDCTVBitmapUpdate *I);

/// Get the region bitmaps for an increment, creating them if necessary.
///
/// If the bitmap array doesn't yet exist, the profile data variables
/// referring to them will also be created.
GlobalVariable *getOrCreateRegionBitmaps(InstrProfMCDCBitmapInstBase *Inc);

/// Create the MC/DC bitmap as a byte-aligned array of bytes associated with
/// an MC/DC Decision region. The number of bytes required is indicated by
/// the intrinsic used (type InstrProfMCDCBitmapInstBase). This is called
/// as part of setupProfileSection() and is conceptually very similar to
/// what is done for profile data counters in createRegionCounters().
GlobalVariable *createRegionBitmaps(InstrProfMCDCBitmapInstBase *Inc,
StringRef Name,
GlobalValue::LinkageTypes Linkage);

/// Set Comdat property of GV, if required.
void maybeSetComdat(GlobalVariable *GV, Function *Fn, StringRef VarName);

/// Setup the sections into which counters and bitmaps are allocated.
GlobalVariable *setupProfileSection(InstrProfInstBase *Inc,
InstrProfSectKind IPSK);

/// Create INSTR_PROF_DATA variable for counters and bitmaps.
void createDataVariable(InstrProfCntrInstBase *Inc);

/// Emit the section with compressed function names.
void emitNameData();

/// Emit value nodes section for value profiling.
void emitVNodes();

/// Emit runtime registration functions for each profile data variable.
void emitRegistration();

/// Emit the necessary plumbing to pull in the runtime initialization.
/// Returns true if a change was made.
bool emitRuntimeHook();

/// Add uses of our data variables and runtime hook.
void emitUses();

/// Create a static initializer for our data, on platforms that need it,
/// and for any profile output file that was specified.
void emitInitialization();
};

} // end namespace llvm

#endif // LLVM_TRANSFORMS_INSTRUMENTATION_INSTRPROFILING_H
149 changes: 149 additions & 0 deletions llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,155 @@ cl::opt<bool> SkipRetExitBlock(
"skip-ret-exit-block", cl::init(true),
cl::desc("Suppress counter promotion if exit blocks contain ret."));

using LoadStorePair = std::pair<Instruction *, Instruction *>;

class InstrProfiling final {
public:
InstrProfiling(Module &M, const InstrProfOptions &Options,
std::function<const TargetLibraryInfo &(Function &F)> GetTLI,
bool IsCS)
: M(M), Options(Options), TT(Triple(M.getTargetTriple())), IsCS(IsCS),
GetTLI(GetTLI) {}

bool lower();

private:
Module &M;
const InstrProfOptions Options;
const Triple TT;
// Is this lowering for the context-sensitive instrumentation.
const bool IsCS;

std::function<const TargetLibraryInfo &(Function &F)> GetTLI;
struct PerFunctionProfileData {
uint32_t NumValueSites[IPVK_Last + 1] = {};
GlobalVariable *RegionCounters = nullptr;
GlobalVariable *DataVar = nullptr;
GlobalVariable *RegionBitmaps = nullptr;
uint32_t NumBitmapBytes = 0;

PerFunctionProfileData() = default;
};
DenseMap<GlobalVariable *, PerFunctionProfileData> ProfileDataMap;
/// If runtime relocation is enabled, this maps functions to the load
/// instruction that produces the profile relocation bias.
DenseMap<const Function *, LoadInst *> FunctionToProfileBiasMap;
std::vector<GlobalValue *> CompilerUsedVars;
std::vector<GlobalValue *> UsedVars;
std::vector<GlobalVariable *> ReferencedNames;
GlobalVariable *NamesVar = nullptr;
size_t NamesSize = 0;

// vector of counter load/store pairs to be register promoted.
std::vector<LoadStorePair> PromotionCandidates;

int64_t TotalCountersPromoted = 0;

/// Lower instrumentation intrinsics in the function. Returns true if there
/// any lowering.
bool lowerIntrinsics(Function *F);

/// Register-promote counter loads and stores in loops.
void promoteCounterLoadStores(Function *F);

/// Returns true if relocating counters at runtime is enabled.
bool isRuntimeCounterRelocationEnabled() const;

/// Returns true if profile counter update register promotion is enabled.
bool isCounterPromotionEnabled() const;

/// Count the number of instrumented value sites for the function.
void computeNumValueSiteCounts(InstrProfValueProfileInst *Ins);

/// Replace instrprof.value.profile with a call to runtime library.
void lowerValueProfileInst(InstrProfValueProfileInst *Ins);

/// Replace instrprof.cover with a store instruction to the coverage byte.
void lowerCover(InstrProfCoverInst *Inc);

/// Replace instrprof.timestamp with a call to
/// INSTR_PROF_PROFILE_SET_TIMESTAMP.
void lowerTimestamp(InstrProfTimestampInst *TimestampInstruction);

/// Replace instrprof.increment with an increment of the appropriate value.
void lowerIncrement(InstrProfIncrementInst *Inc);

/// Force emitting of name vars for unused functions.
void lowerCoverageData(GlobalVariable *CoverageNamesVar);

/// Replace instrprof.mcdc.tvbitmask.update with a shift and or instruction
/// using the index represented by the a temp value into a bitmap.
void lowerMCDCTestVectorBitmapUpdate(InstrProfMCDCTVBitmapUpdate *Ins);

/// Replace instrprof.mcdc.temp.update with a shift and or instruction using
/// the corresponding condition ID.
void lowerMCDCCondBitmapUpdate(InstrProfMCDCCondBitmapUpdate *Ins);

/// Compute the address of the counter value that this profiling instruction
/// acts on.
Value *getCounterAddress(InstrProfCntrInstBase *I);

/// Get the region counters for an increment, creating them if necessary.
///
/// If the counter array doesn't yet exist, the profile data variables
/// referring to them will also be created.
GlobalVariable *getOrCreateRegionCounters(InstrProfCntrInstBase *Inc);

/// Create the region counters.
GlobalVariable *createRegionCounters(InstrProfCntrInstBase *Inc,
StringRef Name,
GlobalValue::LinkageTypes Linkage);

/// Compute the address of the test vector bitmap that this profiling
/// instruction acts on.
Value *getBitmapAddress(InstrProfMCDCTVBitmapUpdate *I);

/// Get the region bitmaps for an increment, creating them if necessary.
///
/// If the bitmap array doesn't yet exist, the profile data variables
/// referring to them will also be created.
GlobalVariable *getOrCreateRegionBitmaps(InstrProfMCDCBitmapInstBase *Inc);

/// Create the MC/DC bitmap as a byte-aligned array of bytes associated with
/// an MC/DC Decision region. The number of bytes required is indicated by
/// the intrinsic used (type InstrProfMCDCBitmapInstBase). This is called
/// as part of setupProfileSection() and is conceptually very similar to
/// what is done for profile data counters in createRegionCounters().
GlobalVariable *createRegionBitmaps(InstrProfMCDCBitmapInstBase *Inc,
StringRef Name,
GlobalValue::LinkageTypes Linkage);

/// Set Comdat property of GV, if required.
void maybeSetComdat(GlobalVariable *GV, Function *Fn, StringRef VarName);

/// Setup the sections into which counters and bitmaps are allocated.
GlobalVariable *setupProfileSection(InstrProfInstBase *Inc,
InstrProfSectKind IPSK);

/// Create INSTR_PROF_DATA variable for counters and bitmaps.
void createDataVariable(InstrProfCntrInstBase *Inc);

/// Emit the section with compressed function names.
void emitNameData();

/// Emit value nodes section for value profiling.
void emitVNodes();

/// Emit runtime registration functions for each profile data variable.
void emitRegistration();

/// Emit the necessary plumbing to pull in the runtime initialization.
/// Returns true if a change was made.
bool emitRuntimeHook();

/// Add uses of our data variables and runtime hook.
void emitUses();

/// Create a static initializer for our data, on platforms that need it,
/// and for any profile output file that was specified.
void emitInitialization();
};

///
/// A helper class to promote one counter RMW operation in the loop
/// into register update.
Expand Down