Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
14 pmbaty 1
//===--- PerfMonitor.h --- Monitor time spent in scops --------------------===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
 
9
#ifndef PERF_MONITOR_H
10
#define PERF_MONITOR_H
11
 
12
#include "polly/CodeGen/IRBuilder.h"
13
 
14
namespace polly {
15
 
16
class PerfMonitor final {
17
public:
18
  /// Create a new performance monitor.
19
  ///
20
  /// @param S The scop for which to generate fine-grained performance
21
  ///          monitoring information.
22
  /// @param M The module for which to generate the performance monitor.
23
  PerfMonitor(const Scop &S, llvm::Module *M);
24
 
25
  /// Initialize the performance monitor.
26
  ///
27
  /// Ensure that all global variables, functions, and callbacks needed to
28
  /// manage the performance monitor are initialized and registered.
29
  void initialize();
30
 
31
  /// Mark the beginning of a timing region.
32
  ///
33
  /// @param InsertBefore The instruction before which the timing region starts.
34
  void insertRegionStart(llvm::Instruction *InsertBefore);
35
 
36
  /// Mark the end of a timing region.
37
  ///
38
  /// @param InsertBefore The instruction before which the timing region starts.
39
  void insertRegionEnd(llvm::Instruction *InsertBefore);
40
 
41
private:
42
  llvm::Module *M;
43
  PollyIRBuilder Builder;
44
 
45
  // The scop to profile against.
46
  const Scop &S;
47
 
48
  /// Indicates if performance profiling is supported on this architecture.
49
  bool Supported;
50
 
51
  /// The cycle counter at the beginning of the program execution.
52
  llvm::Value *CyclesTotalStartPtr;
53
 
54
  /// The total number of cycles spent in the current scop S.
55
  llvm::Value *CyclesInCurrentScopPtr;
56
 
57
  /// The total number of times the current scop S is executed.
58
  llvm::Value *TripCountForCurrentScopPtr;
59
 
60
  /// The total number of cycles spent within scops.
61
  llvm::Value *CyclesInScopsPtr;
62
 
63
  /// The value of the cycle counter at the beginning of the last scop.
64
  llvm::Value *CyclesInScopStartPtr;
65
 
66
  /// A global variable, that keeps track if the performance monitor
67
  /// initialization has already been run.
68
  llvm::Value *AlreadyInitializedPtr;
69
 
70
  llvm::Function *insertInitFunction(llvm::Function *FinalReporting);
71
 
72
  /// Add Function @p to list of global constructors
73
  ///
74
  /// If no global constructors are available in this current module, insert
75
  /// a new list of global constructors containing @p Fn as only global
76
  /// constructor. Otherwise, append @p Fn to the list of global constructors.
77
  ///
78
  /// All functions listed as global constructors are executed before the
79
  /// main() function is called.
80
  ///
81
  /// @param Fn Function to add to global constructors
82
  void addToGlobalConstructors(llvm::Function *Fn);
83
 
84
  /// Add global variables to module.
85
  ///
86
  /// Insert a set of global variables that are used to track performance,
87
  /// into the module (or obtain references to them if they already exist).
88
  void addGlobalVariables();
89
 
90
  /// Add per-scop tracking to module.
91
  ///
92
  /// Insert the global variable which is used to track the number of cycles
93
  /// this scop runs.
94
  void addScopCounter();
95
 
96
  /// Get a reference to the intrinsic "{ i64, i32 } @llvm.x86.rdtscp()".
97
  ///
98
  /// The rdtscp function returns the current value of the processor's
99
  /// time-stamp counter as well as the current CPU identifier. On modern x86
100
  /// systems, the returned value is independent of the dynamic clock frequency
101
  /// and consistent across multiple cores. It can consequently be used to get
102
  /// accurate and low-overhead timing information. Even though the counter is
103
  /// wrapping, it can be reliably used even for measuring longer time
104
  /// intervals, as on a 1 GHz processor the counter only wraps every 545 years.
105
  ///
106
  /// The RDTSCP instruction is "pseudo" serializing:
107
  ///
108
  /// "“The RDTSCP instruction waits until all previous instructions have been
109
  /// executed before reading the counter. However, subsequent instructions may
110
  /// begin execution before the read operation is performed.”
111
  ///
112
  /// To ensure that no later instructions are scheduled before the RDTSCP
113
  /// instruction it is often recommended to schedule a cpuid call after the
114
  /// RDTSCP instruction. We do not do this yet, trading some imprecision in
115
  /// our timing for a reduced overhead in our timing.
116
  ///
117
  /// @returns A reference to the declaration of @llvm.x86.rdtscp.
118
  llvm::Function *getRDTSCP();
119
 
120
  /// Get a reference to "int atexit(void (*function)(void))" function.
121
  ///
122
  /// This function allows to register function pointers that must be executed
123
  /// when the program is terminated.
124
  ///
125
  /// @returns A reference to @atexit().
126
  llvm::Function *getAtExit();
127
 
128
  /// Create function "__polly_perf_final_reporting".
129
  ///
130
  /// This function finalizes the performance measurements and prints the
131
  /// results to stdout. It is expected to be registered with 'atexit()'.
132
  llvm::Function *insertFinalReporting();
133
 
134
  /// Append Scop reporting data to "__polly_perf_final_reporting".
135
  ///
136
  /// This function appends the current scop (S)'s information to the final
137
  /// printing function.
138
  void AppendScopReporting();
139
};
140
} // namespace polly
141
 
142
#endif