Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:48:11

0001 //===--- PerfMonitor.h --- Monitor time spent in scops --------------------===//
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 #ifndef PERF_MONITOR_H
0010 #define PERF_MONITOR_H
0011 
0012 #include "polly/CodeGen/IRBuilder.h"
0013 
0014 namespace polly {
0015 
0016 class PerfMonitor final {
0017 public:
0018   /// Create a new performance monitor.
0019   ///
0020   /// @param S The scop for which to generate fine-grained performance
0021   ///          monitoring information.
0022   /// @param M The module for which to generate the performance monitor.
0023   PerfMonitor(const Scop &S, llvm::Module *M);
0024 
0025   /// Initialize the performance monitor.
0026   ///
0027   /// Ensure that all global variables, functions, and callbacks needed to
0028   /// manage the performance monitor are initialized and registered.
0029   void initialize();
0030 
0031   /// Mark the beginning of a timing region.
0032   ///
0033   /// @param InsertBefore The instruction before which the timing region starts.
0034   void insertRegionStart(llvm::Instruction *InsertBefore);
0035 
0036   /// Mark the end of a timing region.
0037   ///
0038   /// @param InsertBefore The instruction before which the timing region starts.
0039   void insertRegionEnd(llvm::Instruction *InsertBefore);
0040 
0041 private:
0042   llvm::Module *M;
0043   PollyIRBuilder Builder;
0044 
0045   // The scop to profile against.
0046   const Scop &S;
0047 
0048   /// Indicates if performance profiling is supported on this architecture.
0049   bool Supported;
0050 
0051   /// The cycle counter at the beginning of the program execution.
0052   llvm::Value *CyclesTotalStartPtr;
0053 
0054   /// The total number of cycles spent in the current scop S.
0055   llvm::Value *CyclesInCurrentScopPtr;
0056 
0057   /// The total number of times the current scop S is executed.
0058   llvm::Value *TripCountForCurrentScopPtr;
0059 
0060   /// The total number of cycles spent within scops.
0061   llvm::Value *CyclesInScopsPtr;
0062 
0063   /// The value of the cycle counter at the beginning of the last scop.
0064   llvm::Value *CyclesInScopStartPtr;
0065 
0066   /// A global variable, that keeps track if the performance monitor
0067   /// initialization has already been run.
0068   llvm::Value *AlreadyInitializedPtr;
0069 
0070   llvm::Function *insertInitFunction(llvm::Function *FinalReporting);
0071 
0072   /// Add Function @p to list of global constructors
0073   ///
0074   /// If no global constructors are available in this current module, insert
0075   /// a new list of global constructors containing @p Fn as only global
0076   /// constructor. Otherwise, append @p Fn to the list of global constructors.
0077   ///
0078   /// All functions listed as global constructors are executed before the
0079   /// main() function is called.
0080   ///
0081   /// @param Fn Function to add to global constructors
0082   void addToGlobalConstructors(llvm::Function *Fn);
0083 
0084   /// Add global variables to module.
0085   ///
0086   /// Insert a set of global variables that are used to track performance,
0087   /// into the module (or obtain references to them if they already exist).
0088   void addGlobalVariables();
0089 
0090   /// Add per-scop tracking to module.
0091   ///
0092   /// Insert the global variable which is used to track the number of cycles
0093   /// this scop runs.
0094   void addScopCounter();
0095 
0096   /// Get a reference to the intrinsic "{ i64, i32 } @llvm.x86.rdtscp()".
0097   ///
0098   /// The rdtscp function returns the current value of the processor's
0099   /// time-stamp counter as well as the current CPU identifier. On modern x86
0100   /// systems, the returned value is independent of the dynamic clock frequency
0101   /// and consistent across multiple cores. It can consequently be used to get
0102   /// accurate and low-overhead timing information. Even though the counter is
0103   /// wrapping, it can be reliably used even for measuring longer time
0104   /// intervals, as on a 1 GHz processor the counter only wraps every 545 years.
0105   ///
0106   /// The RDTSCP instruction is "pseudo" serializing:
0107   ///
0108   /// "“The RDTSCP instruction waits until all previous instructions have been
0109   /// executed before reading the counter. However, subsequent instructions may
0110   /// begin execution before the read operation is performed.”
0111   ///
0112   /// To ensure that no later instructions are scheduled before the RDTSCP
0113   /// instruction it is often recommended to schedule a cpuid call after the
0114   /// RDTSCP instruction. We do not do this yet, trading some imprecision in
0115   /// our timing for a reduced overhead in our timing.
0116   ///
0117   /// @returns A reference to the declaration of @llvm.x86.rdtscp.
0118   llvm::Function *getRDTSCP();
0119 
0120   /// Get a reference to "int atexit(void (*function)(void))" function.
0121   ///
0122   /// This function allows to register function pointers that must be executed
0123   /// when the program is terminated.
0124   ///
0125   /// @returns A reference to @atexit().
0126   llvm::Function *getAtExit();
0127 
0128   /// Create function "__polly_perf_final_reporting".
0129   ///
0130   /// This function finalizes the performance measurements and prints the
0131   /// results to stdout. It is expected to be registered with 'atexit()'.
0132   llvm::Function *insertFinalReporting();
0133 
0134   /// Append Scop reporting data to "__polly_perf_final_reporting".
0135   ///
0136   /// This function appends the current scop (S)'s information to the final
0137   /// printing function.
0138   void AppendScopReporting();
0139 };
0140 } // namespace polly
0141 
0142 #endif