Index: include/llvm/InitializePasses.h =================================================================== --- include/llvm/InitializePasses.h +++ include/llvm/InitializePasses.h @@ -115,25 +115,25 @@ void initializeDomOnlyViewerPass(PassRegistry&); void initializeDomPrinterPass(PassRegistry&); void initializeDomViewerPass(PassRegistry&); -void initializeDominanceFrontierWrapperPassPass(PassRegistry&); -void initializeDominatorTreeWrapperPassPass(PassRegistry&); -void initializeEarlyIfConverterPass(PassRegistry&); -void initializeEdgeBundlesPass(PassRegistry&); -void initializeExpandPostRAPass(PassRegistry&); +void initializeDominanceFrontierWrapperPassPass(PassRegistry &); +void initializeDominatorTreeWrapperPassPass(PassRegistry &); +void initializeEarlyIfConverterPass(PassRegistry &); +void initializeEdgeBundlesPass(PassRegistry &); +void initializeExpandPostRAPass(PassRegistry &); void initializeAAResultsWrapperPassPass(PassRegistry &); -void initializeGCOVProfilerPass(PassRegistry&); -void initializePGOInstrumentationGenPass(PassRegistry&); -void initializePGOInstrumentationUsePass(PassRegistry&); -void initializeInstrProfilingPass(PassRegistry&); -void initializeAddressSanitizerPass(PassRegistry&); -void initializeAddressSanitizerModulePass(PassRegistry&); -void initializeMemorySanitizerPass(PassRegistry&); -void initializeThreadSanitizerPass(PassRegistry&); -void initializeSanitizerCoverageModulePass(PassRegistry&); -void initializeDataFlowSanitizerPass(PassRegistry&); -void initializeScalarizerPass(PassRegistry&); +void initializeGCOVProfilerPass(PassRegistry &); +void initializePGOInstrumentationGenPass(PassRegistry &); +void initializePGOInstrumentationUsePass(PassRegistry &); +void initializeInstrProfilingLegacyWrapperPassPass(PassRegistry &); +void initializeAddressSanitizerPass(PassRegistry &); +void initializeAddressSanitizerModulePass(PassRegistry &); +void initializeMemorySanitizerPass(PassRegistry &); +void initializeThreadSanitizerPass(PassRegistry &); +void initializeSanitizerCoverageModulePass(PassRegistry &); +void initializeDataFlowSanitizerPass(PassRegistry &); +void initializeScalarizerPass(PassRegistry &); void initializeEarlyCSELegacyPassPass(PassRegistry &); -void initializeEliminateAvailableExternallyPass(PassRegistry&); +void initializeEliminateAvailableExternallyPass(PassRegistry &); void initializeExpandISelPseudosPass(PassRegistry&); void initializeForceFunctionAttrsLegacyPassPass(PassRegistry&); void initializeGCMachineCodeAnalysisPass(PassRegistry&); Index: include/llvm/LinkAllPasses.h =================================================================== --- include/llvm/LinkAllPasses.h +++ include/llvm/LinkAllPasses.h @@ -82,25 +82,25 @@ (void) llvm::createDeadCodeEliminationPass(); (void) llvm::createDeadInstEliminationPass(); (void) llvm::createDeadStoreEliminationPass(); - (void) llvm::createDependenceAnalysisPass(); - (void) llvm::createDivergenceAnalysisPass(); - (void) llvm::createDomOnlyPrinterPass(); - (void) llvm::createDomPrinterPass(); - (void) llvm::createDomOnlyViewerPass(); - (void) llvm::createDomViewerPass(); - (void) llvm::createGCOVProfilerPass(); - (void) llvm::createPGOInstrumentationGenPass(); - (void) llvm::createPGOInstrumentationUsePass(); - (void) llvm::createInstrProfilingPass(); - (void) llvm::createFunctionImportPass(); - (void) llvm::createFunctionInliningPass(); - (void) llvm::createAlwaysInlinerPass(); - (void) llvm::createGlobalDCEPass(); - (void) llvm::createGlobalOptimizerPass(); - (void) llvm::createGlobalsAAWrapperPass(); - (void) llvm::createIPConstantPropagationPass(); - (void) llvm::createIPSCCPPass(); - (void) llvm::createInductiveRangeCheckEliminationPass(); + (void)llvm::createDependenceAnalysisPass(); + (void)llvm::createDivergenceAnalysisPass(); + (void)llvm::createDomOnlyPrinterPass(); + (void)llvm::createDomPrinterPass(); + (void)llvm::createDomOnlyViewerPass(); + (void)llvm::createDomViewerPass(); + (void)llvm::createGCOVProfilerPass(); + (void)llvm::createPGOInstrumentationGenPass(); + (void)llvm::createPGOInstrumentationUsePass(); + (void)llvm::createInstrProfilingLegacyPass(); + (void)llvm::createFunctionImportPass(); + (void)llvm::createFunctionInliningPass(); + (void)llvm::createAlwaysInlinerPass(); + (void)llvm::createGlobalDCEPass(); + (void)llvm::createGlobalOptimizerPass(); + (void)llvm::createGlobalsAAWrapperPass(); + (void)llvm::createIPConstantPropagationPass(); + (void)llvm::createIPSCCPPass(); + (void)llvm::createInductiveRangeCheckEliminationPass(); (void) llvm::createIndVarSimplifyPass(); (void) llvm::createInstructionCombiningPass(); (void) llvm::createInternalizePass(); Index: include/llvm/Transforms/Instrumentation.h =================================================================== --- include/llvm/Transforms/Instrumentation.h +++ include/llvm/Transforms/Instrumentation.h @@ -16,6 +16,9 @@ #include "llvm/ADT/StringRef.h" #include "llvm/IR/BasicBlock.h" +#include "llvm/IR/IntrinsicInst.h" +#include "llvm/IR/PassManager.h" +#include "llvm/ProfileData/InstrProf.h" #include #if defined(__GNUC__) && defined(__linux__) && !defined(ANDROID) @@ -95,8 +98,91 @@ std::string InstrProfileOutput; }; +class InstrProfiling { +public: + InstrProfiling() {} + InstrProfiling(const InstrProfOptions &Options) : Options(Options) {} + + bool run(Module &M); + +private: + InstrProfOptions Options; + Module *M; + typedef struct PerFunctionProfileData { + uint32_t NumValueSites[IPVK_Last + 1]; + GlobalVariable *RegionCounters; + GlobalVariable *DataVar; + PerFunctionProfileData() : RegionCounters(nullptr), DataVar(nullptr) { + memset(NumValueSites, 0, sizeof(uint32_t) * (IPVK_Last + 1)); + } + } PerFunctionProfileData; + DenseMap ProfileDataMap; + std::vector UsedVars; + std::vector ReferencedNames; + GlobalVariable *NamesVar; + size_t NamesSize; + + bool isMachO() const; + + /// Get the section name for the counter variables. + StringRef getCountersSection() const; + + /// Get the section name for the name variables. + StringRef getNameSection() const; + + /// Get the section name for the profile data variables. + StringRef getDataSection() const; + + /// Get the section name for the coverage mapping data. + StringRef getCoverageSection() 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_increment with an increment of the appropriate value. + void lowerIncrement(InstrProfIncrementInst *Inc); + + /// Force emitting of name vars for unused functions. + void lowerCoverageData(GlobalVariable *CoverageNamesVar); + + /// 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(InstrProfIncrementInst *Inc); + + /// Emit the section with compressed function names. + void emitNameData(); + + /// Emit runtime registration functions for each profile data variable. + void emitRegistration(); + + /// Emit the necessary plumbing to pull in the runtime initialization. + void 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(); +}; + +/// Instrumenation based profiling lowering pass. This pass lowers +/// the profile instrumented code generated by FE or the IR based +/// instrumentation pass. +struct InstrProfilingPass : PassInfoMixin { + InstrProfiling InstrProf; + InstrProfilingPass() : InstrProf() {} + InstrProfilingPass(const InstrProfOptions &O) : InstrProf(O) {} + PreservedAnalyses run(Module &M, AnalysisManager &AM); +}; + /// Insert frontend instrumentation based profiling. -ModulePass *createInstrProfilingPass( +ModulePass *createInstrProfilingLegacyPass( const InstrProfOptions &Options = InstrProfOptions()); // Insert AddressSanitizer (address sanity checking) instrumentation Index: lib/Passes/PassBuilder.cpp =================================================================== --- lib/Passes/PassBuilder.cpp +++ lib/Passes/PassBuilder.cpp @@ -49,10 +49,11 @@ #include "llvm/Transforms/IPO/InferFunctionAttrs.h" #include "llvm/Transforms/IPO/StripDeadPrototypes.h" #include "llvm/Transforms/InstCombine/InstCombine.h" +#include "llvm/Transforms/Instrumentation.h" #include "llvm/Transforms/Scalar/ADCE.h" #include "llvm/Transforms/Scalar/EarlyCSE.h" -#include "llvm/Transforms/Scalar/LowerExpectIntrinsic.h" #include "llvm/Transforms/Scalar/GVN.h" +#include "llvm/Transforms/Scalar/LowerExpectIntrinsic.h" #include "llvm/Transforms/Scalar/SROA.h" #include "llvm/Transforms/Scalar/SimplifyCFG.h" #include Index: lib/Passes/PassRegistry.def =================================================================== --- lib/Passes/PassRegistry.def +++ lib/Passes/PassRegistry.def @@ -38,6 +38,7 @@ MODULE_PASS("forceattrs", ForceFunctionAttrsPass()) MODULE_PASS("inferattrs", InferFunctionAttrsPass()) MODULE_PASS("invalidate", InvalidateAllAnalysesPass()) +MODULE_PASS("instrprof", InstrProfilingPass()) MODULE_PASS("no-op-module", NoOpModulePass()) MODULE_PASS("print", PrintModulePass(dbgs())) MODULE_PASS("print-callgraph", CallGraphPrinterPass(dbgs())) Index: lib/Transforms/IPO/PassManagerBuilder.cpp =================================================================== --- lib/Transforms/IPO/PassManagerBuilder.cpp +++ lib/Transforms/IPO/PassManagerBuilder.cpp @@ -220,7 +220,7 @@ // Add the profile lowering pass. InstrProfOptions Options; Options.InstrProfileOutput = PGOInstrGen; - MPM.add(createInstrProfilingPass(Options)); + MPM.add(createInstrProfilingLegacyPass(Options)); } if (!PGOInstrUse.empty()) MPM.add(createPGOInstrumentationUsePass(PGOInstrUse)); Index: lib/Transforms/Instrumentation/InstrProfiling.cpp =================================================================== --- lib/Transforms/Instrumentation/InstrProfiling.cpp +++ lib/Transforms/Instrumentation/InstrProfiling.cpp @@ -31,113 +31,70 @@ cl::desc("Enable name string compression"), cl::init(true)); -class InstrProfiling : public ModulePass { +class InstrProfilingLegacyWrapperPass : public ModulePass { + InstrProfiling InstrProf; + public: static char ID; - - InstrProfiling() : ModulePass(ID) {} - - InstrProfiling(const InstrProfOptions &Options) - : ModulePass(ID), Options(Options) {} - + InstrProfilingLegacyWrapperPass() : ModulePass(ID), InstrProf() {} + InstrProfilingLegacyWrapperPass(const InstrProfOptions &Options) + : ModulePass(ID), InstrProf(Options) {} const char *getPassName() const override { return "Frontend instrumentation-based coverage lowering"; } - bool runOnModule(Module &M) override; + bool runOnModule(Module &M) override { return InstrProf.run(M); } void getAnalysisUsage(AnalysisUsage &AU) const override { AU.setPreservesCFG(); } +}; -private: - InstrProfOptions Options; - Module *M; - typedef struct PerFunctionProfileData { - uint32_t NumValueSites[IPVK_Last+1]; - GlobalVariable* RegionCounters; - GlobalVariable* DataVar; - PerFunctionProfileData() : RegionCounters(nullptr), DataVar(nullptr) { - memset(NumValueSites, 0, sizeof(uint32_t) * (IPVK_Last+1)); - } - } PerFunctionProfileData; - DenseMap ProfileDataMap; - std::vector UsedVars; - std::vector ReferencedNames; - GlobalVariable *NamesVar; - size_t NamesSize; - - bool isMachO() const { - return Triple(M->getTargetTriple()).isOSBinFormatMachO(); - } - - /// Get the section name for the counter variables. - StringRef getCountersSection() const { - return getInstrProfCountersSectionName(isMachO()); - } - - /// Get the section name for the name variables. - StringRef getNameSection() const { - return getInstrProfNameSectionName(isMachO()); - } - - /// Get the section name for the profile data variables. - StringRef getDataSection() const { - return getInstrProfDataSectionName(isMachO()); - } - - /// Get the section name for the coverage mapping data. - StringRef getCoverageSection() const { - return getInstrProfCoverageSectionName(isMachO()); - } - - /// 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_increment with an increment of the appropriate value. - void lowerIncrement(InstrProfIncrementInst *Inc); - - /// Force emitting of name vars for unused functions. - void lowerCoverageData(GlobalVariable *CoverageNamesVar); +} // anonymous namespace - /// 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(InstrProfIncrementInst *Inc); +PreservedAnalyses InstrProfilingPass::run(Module &M, + AnalysisManager &AM) { + if (!InstrProf.run(M)) + return PreservedAnalyses::all(); - /// Emit the section with compressed function names. - void emitNameData(); + return PreservedAnalyses::none(); +} - /// Emit runtime registration functions for each profile data variable. - void emitRegistration(); +char InstrProfilingLegacyWrapperPass::ID = 0; +INITIALIZE_PASS(InstrProfilingLegacyWrapperPass, "instrprof", + "Frontend instrumentation-based coverage lowering.", false, + false) - /// Emit the necessary plumbing to pull in the runtime initialization. - void emitRuntimeHook(); +ModulePass * +llvm::createInstrProfilingLegacyPass(const InstrProfOptions &Options) { + return new InstrProfilingLegacyWrapperPass(Options); +} - /// Add uses of our data variables and runtime hook. - void emitUses(); +bool InstrProfiling::isMachO() const { + return Triple(M->getTargetTriple()).isOSBinFormatMachO(); +} - /// Create a static initializer for our data, on platforms that need it, - /// and for any profile output file that was specified. - void emitInitialization(); -}; +/// Get the section name for the counter variables. +StringRef InstrProfiling::getCountersSection() const { + return getInstrProfCountersSectionName(isMachO()); +} -} // anonymous namespace +/// Get the section name for the name variables. +StringRef InstrProfiling::getNameSection() const { + return getInstrProfNameSectionName(isMachO()); +} -char InstrProfiling::ID = 0; -INITIALIZE_PASS(InstrProfiling, "instrprof", - "Frontend instrumentation-based coverage lowering.", false, - false) +/// Get the section name for the profile data variables. +StringRef InstrProfiling::getDataSection() const { + return getInstrProfDataSectionName(isMachO()); +} -ModulePass *llvm::createInstrProfilingPass(const InstrProfOptions &Options) { - return new InstrProfiling(Options); +/// Get the section name for the coverage mapping data. +StringRef InstrProfiling::getCoverageSection() const { + return getInstrProfCoverageSectionName(isMachO()); } -bool InstrProfiling::runOnModule(Module &M) { +bool InstrProfiling::run(Module &M) { bool MadeChange = false; this->M = &M; Index: lib/Transforms/Instrumentation/Instrumentation.cpp =================================================================== --- lib/Transforms/Instrumentation/Instrumentation.cpp +++ lib/Transforms/Instrumentation/Instrumentation.cpp @@ -62,7 +62,7 @@ initializeGCOVProfilerPass(Registry); initializePGOInstrumentationGenPass(Registry); initializePGOInstrumentationUsePass(Registry); - initializeInstrProfilingPass(Registry); + initializeInstrProfilingLegacyWrapperPassPass(Registry); initializeMemorySanitizerPass(Registry); initializeThreadSanitizerPass(Registry); initializeSanitizerCoverageModulePass(Registry); Index: test/Instrumentation/InstrProfiling/PR23499.ll =================================================================== --- test/Instrumentation/InstrProfiling/PR23499.ll +++ test/Instrumentation/InstrProfiling/PR23499.ll @@ -4,6 +4,7 @@ ; RUN: opt < %s -mtriple=x86_64-apple-macosx10.10.0 -instrprof -S | FileCheck %s ; RUN: opt < %s -mtriple=x86_64-unknown-linux -instrprof -S | FileCheck %s +; RUN: opt < %s -mtriple=x86_64-unknown-linux -passes=instrprof -S | FileCheck %s ; RUN: opt < %s -mtriple=x86_64-pc-win32-coff -instrprof -S | FileCheck %s --check-prefix=COFF $_Z3barIvEvv = comdat any Index: test/Instrumentation/InstrProfiling/linkage.ll =================================================================== --- test/Instrumentation/InstrProfiling/linkage.ll +++ test/Instrumentation/InstrProfiling/linkage.ll @@ -2,6 +2,8 @@ ; RUN: opt < %s -mtriple=x86_64-apple-macosx10.10.0 -instrprof -S | FileCheck %s --check-prefix=OTHER --check-prefix=COMMON ; RUN: opt < %s -mtriple=x86_64-unknown-linux -instrprof -S | FileCheck %s --check-prefix=LINUX --check-prefix=COMMON +; RUN: opt < %s -mtriple=x86_64-apple-macosx10.10.0 -passes=instrprof -S | FileCheck %s --check-prefix=OTHER --check-prefix=COMMON +; RUN: opt < %s -mtriple=x86_64-unknown-linux -passes=instrprof -S | FileCheck %s --check-prefix=LINUX --check-prefix=COMMON @__profn_foo = hidden constant [3 x i8] c"foo" @__profn_foo_weak = weak hidden constant [8 x i8] c"foo_weak" Index: test/Instrumentation/InstrProfiling/no-counters.ll =================================================================== --- test/Instrumentation/InstrProfiling/no-counters.ll +++ test/Instrumentation/InstrProfiling/no-counters.ll @@ -1,6 +1,7 @@ ;; No instrumentation should be emitted if there are no counter increments. ; RUN: opt < %s -instrprof -S | FileCheck %s +; RUN: opt < %s -passes=instrprof -S | FileCheck %s ; CHECK-NOT: @__profc ; CHECK-NOT: @__profd ; CHECK-NOT: @__llvm_profile_runtime Index: test/Instrumentation/InstrProfiling/noruntime.ll =================================================================== --- test/Instrumentation/InstrProfiling/noruntime.ll +++ test/Instrumentation/InstrProfiling/noruntime.ll @@ -1,6 +1,7 @@ ;; Check that we don't emit the runtime hooks if the user provided them. ; RUN: opt < %s -instrprof -S | FileCheck %s +; RUN: opt < %s -passes=instrprof -S | FileCheck %s ; CHECK-NOT: define {{.*}} @__llvm_profile_runtime_user() ; CHECK-NOT: load i32, i32* @__llvm_profile_runtime Index: test/Instrumentation/InstrProfiling/platform.ll =================================================================== --- test/Instrumentation/InstrProfiling/platform.ll +++ test/Instrumentation/InstrProfiling/platform.ll @@ -2,6 +2,7 @@ ; RUN: opt < %s -mtriple=x86_64-apple-macosx10.10.0 -instrprof -S | FileCheck %s -check-prefix=MACHO ; RUN: opt < %s -mtriple=x86_64-unknown-linux -instrprof -S | FileCheck %s -check-prefix=LINUX +; RUN: opt < %s -mtriple=x86_64-unknown-linux -passes=instrprof -S | FileCheck %s -check-prefix=LINUX ; RUN: opt < %s -mtriple=x86_64-unknown-freebsd -instrprof -S | FileCheck %s -check-prefix=FREEBSD ; RUN: opt < %s -mtriple=x86_64-scei-ps4 -instrprof -S | FileCheck %s -check-prefix=PS4 ; RUN: opt < %s -mtriple=x86_64-pc-solaris -instrprof -S | FileCheck %s -check-prefix=SOLARIS Index: test/Instrumentation/InstrProfiling/profiling.ll =================================================================== --- test/Instrumentation/InstrProfiling/profiling.ll +++ test/Instrumentation/InstrProfiling/profiling.ll @@ -1,4 +1,5 @@ ; RUN: opt < %s -instrprof -S | FileCheck %s +; RUN: opt < %s -passes=instrprof -S | FileCheck %s target triple = "x86_64-apple-macosx10.10.0"