LLVM: lib/IR/PassTimingInfo.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

29#include

30

31using namespace llvm;

32

33#define DEBUG_TYPE "time-passes"

34

35namespace llvm {

36

39

42 cl::desc("Time each pass, printing elapsed time for each on exit"));

43

46 cl::desc("Time each pass run, printing elapsed time for each run on exit"),

48

49namespace {

50namespace legacy {

51

52

53

54

55

56

57

58

59class PassTimingInfo {

60public:

61 using PassInstanceID = void *;

62

63private:

64 StringMap PassIDCountMap;

67

68public:

69

70

71 PassTimingInfo();

72

73

74 ~PassTimingInfo();

75

76

77

78

79

80 static void init();

81

82

83

85

86

88

89 static PassTimingInfo *TheTimeInfo;

90

91private:

93};

94

96

97PassTimingInfo::PassTimingInfo() : TG("pass", "Pass execution timing report") {}

98

99PassTimingInfo::~PassTimingInfo() {

100

101

102 TimingData.clear();

103}

104

105void PassTimingInfo::init() {

107 return;

108

109

110

111

113 TheTimeInfo = &*TTI;

114}

115

116

117void PassTimingInfo::print(raw_ostream *OutStream) {

119}

120

122 unsigned &num = PassIDCountMap[PassID];

123 num++;

124

125 std::string PassDescNumbered =

126 num <= 1 ? PassDesc.str() : formatv("{0} #{1}", PassDesc, num).str();

127 return new Timer(PassID, PassDescNumbered, TG);

128}

129

130Timer *PassTimingInfo::getPassTimer(Pass *P, PassInstanceID Pass) {

131 if (P->getAsPMDataManager())

132 return nullptr;

133

136 std::unique_ptr &T = TimingData[Pass];

137

138 if (T) {

142 PassArgument = PI->getPassArgument();

144 }

145 return T.get();

146}

147

148PassTimingInfo *PassTimingInfo::TheTimeInfo;

149}

150}

151

153 legacy::PassTimingInfo::init();

154 if (legacy::PassTimingInfo::TheTimeInfo)

155 return legacy::PassTimingInfo::TheTimeInfo->getPassTimer(P, P);

156 return nullptr;

157}

158

159

160

162 if (legacy::PassTimingInfo::TheTimeInfo)

163 legacy::PassTimingInfo::TheTimeInfo->print(OutStream);

164}

165

166

167

168

169

170

171

172Timer &TimePassesHandler::getPassTimer(StringRef PassID, bool IsPass) {

173 TimerGroup &TG = IsPass ? PassTG : AnalysisTG;

174 if (!PerRun) {

175 TimerVector &Timers = TimingData[PassID];

176 if (Timers.size() == 0)

177 Timers.emplace_back(new Timer(PassID, PassID, TG));

178 return *Timers.front();

179 }

180

181

182

183 TimerVector &Timers = TimingData[PassID];

184 unsigned Count = Timers.size() + 1;

185

186 std::string FullDesc = formatv("{0} #{1}", PassID, Count).str();

187

188 Timer *T = new Timer(PassID, FullDesc, TG);

189 Timers.emplace_back(T);

190 assert(Count == Timers.size() && "Timers vector not adjusted correctly.");

191

192 return *T;

193}

194

196 : PassTG("pass", "Pass execution timing report"),

197 AnalysisTG("analysis", "Analysis execution timing report"),

199

202

204 OutStream = &Out;

205}

206

208 if (!Enabled)

209 return;

210 std::unique_ptr<raw_ostream> MaybeCreated;

212 if (OutStream) {

213 OS = OutStream;

214 } else {

216 OS = &*MaybeCreated;

217 }

219 AnalysisTG.print(*OS, true);

220}

221

223 dbgs() << "Dumping timers for " << getTypeName()

224 << ":\n\tRunning:\n";

225 for (auto &I : TimingData) {

227 const TimerVector& MyTimers = I.getValue();

228 for (unsigned idx = 0; idx < MyTimers.size(); idx++) {

229 const Timer* MyTimer = MyTimers[idx].get();

230 if (MyTimer && MyTimer->isRunning())

231 dbgs() << "\tTimer " << MyTimer << " for pass " << PassID << "(" << idx << ")\n";

232 }

233 }

234 dbgs() << "\tTriggered:\n";

235 for (auto &I : TimingData) {

237 const TimerVector& MyTimers = I.getValue();

238 for (unsigned idx = 0; idx < MyTimers.size(); idx++) {

239 const Timer* MyTimer = MyTimers[idx].get();

241 dbgs() << "\tTimer " << MyTimer << " for pass " << PassID << "(" << idx << ")\n";

242 }

243 }

244}

245

248 {"PassManager", "PassAdaptor", "AnalysisManagerProxy",

249 "ModuleInlinerWrapperPass", "DevirtSCCRepeatedPass"});

250}

251

252void TimePassesHandler::startPassTimer(StringRef PassID) {

254 return;

255

256

257 if (!PassActiveTimerStack.empty()) {

258 assert(PassActiveTimerStack.back()->isRunning());

259 PassActiveTimerStack.back()->stopTimer();

260 }

261 Timer &MyTimer = getPassTimer(PassID, true);

262 PassActiveTimerStack.push_back(&MyTimer);

265}

266

267void TimePassesHandler::stopPassTimer(StringRef PassID) {

269 return;

270 assert(!PassActiveTimerStack.empty() && "empty stack in popTimer");

271 Timer *MyTimer = PassActiveTimerStack.pop_back_val();

272 assert(MyTimer && "timer should be present");

275

276

277 if (!PassActiveTimerStack.empty()) {

278 assert(!PassActiveTimerStack.back()->isRunning());

279 PassActiveTimerStack.back()->startTimer();

280 }

281}

282

283void TimePassesHandler::startAnalysisTimer(StringRef PassID) {

284

285

286 if (!AnalysisActiveTimerStack.empty()) {

287 assert(AnalysisActiveTimerStack.back()->isRunning());

288 AnalysisActiveTimerStack.back()->stopTimer();

289 }

290

291 Timer &MyTimer = getPassTimer(PassID, false);

292 AnalysisActiveTimerStack.push_back(&MyTimer);

295}

296

297void TimePassesHandler::stopAnalysisTimer(StringRef PassID) {

298 assert(!AnalysisActiveTimerStack.empty() && "empty stack in popTimer");

299 Timer *MyTimer = AnalysisActiveTimerStack.pop_back_val();

300 assert(MyTimer && "timer should be present");

303

304

305 if (!AnalysisActiveTimerStack.empty()) {

306 assert(!AnalysisActiveTimerStack.back()->isRunning());

307 AnalysisActiveTimerStack.back()->startTimer();

308 }

309}

310

312 if (!Enabled)

313 return;

314

316 [this](StringRef P, Any) { this->startPassTimer(P); });

319 this->stopPassTimer(P);

320 });

323 this->stopPassTimer(P);

324 });

326 [this](StringRef P, Any) { this->startAnalysisTimer(P); });

328 [this](StringRef P, Any) { this->stopAnalysisTimer(P); });

329}

330

331}

#define LLVM_DUMP_METHOD

Mark debug helper function definitions like dump() that should not be stripped from debug builds.

PassInstrumentationCallbacks PIC

This file defines the Pass Instrumentation classes that provide instrumentation points into the pass ...

This header defines classes/functions to handle pass execution timing information with interfaces for...

assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())

This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...

static const char PassName[]

ManagedStatic - This transparently changes the behavior of global statics to be lazily constructed on...

PassInfo class - An instance of this class exists for every pass known by the system,...

Pass interface - Implemented by all 'passes'.

static const PassInfo * lookupPassInfo(const void *TI)

A set of analyses that are preserved following a run of a transformation pass.

StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...

StringRef - Represent a constant reference to a string, i.e.

std::string str() const

str - Get the contents as an std::string.

constexpr bool empty() const

empty - Check if the string is empty.

This class implements -time-passes functionality for new pass manager.

void registerCallbacks(PassInstrumentationCallbacks &PIC)

void print()

Prints out timing information and then resets the timers.

void setOutStream(raw_ostream &OutStream)

Set a custom output stream for subsequent reporting.

The TimerGroup class is used to group together related timers into a single report that is printed wh...

void print(raw_ostream &OS, bool ResetAfterPrint=false)

Print any started timers in this group, optionally resetting timers after printing them.

This class is used to track the amount of time spent between invocations of its startTimer()/stopTime...

bool hasTriggered() const

Check if startTimer() has ever been called on this timer.

bool isRunning() const

Check if the timer is currently running.

void stopTimer()

Stop the timer.

void startTimer()

Start the timer running.

This class implements an extremely fast bulk output stream that can only output to a stream.

initializer< Ty > init(const Ty &Val)

LocationClass< Ty > location(Ty &L)

cb< typename detail::callback_traits< F >::result_type, typename detail::callback_traits< F >::arg_type > callback(F CB)

std::lock_guard< SmartMutex< mt_only > > SmartScopedLock

This is an optimization pass for GlobalISel generic memory operations.

std::unique_ptr< raw_ostream > CreateInfoOutputFile()

Return a stream to print our output on.

static cl::opt< bool, true > EnableTimingPerRun("time-passes-per-run", cl::location(TimePassesPerRun), cl::Hidden, cl::desc("Time each pass run, printing elapsed time for each run on exit"), cl::callback([](const bool &) { TimePassesIsEnabled=true;}))

bool TimePassesIsEnabled

If the user specifies the -time-passes argument on an LLVM tool command line then the value of this b...

bool TimePassesPerRun

If TimePassesPerRun is true, there would be one line of report for each pass invocation.

void reportAndResetTimings(raw_ostream *OutStream=nullptr)

If -time-passes has been specified, report the timings immediately and then reset the timers to zero.

Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr)

auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)

Timer * getPassTimer(Pass *)

Request the timer for this legacy-pass-manager's pass instance.

static bool shouldIgnorePass(StringRef PassID)

raw_ostream & dbgs()

dbgs() - This returns a reference to a raw_ostream for debugging messages.

bool isSpecialPass(StringRef PassID, const std::vector< StringRef > &Specials)

static cl::opt< bool, true > EnableTiming("time-passes", cl::location(TimePassesIsEnabled), cl::Hidden, cl::desc("Time each pass, printing elapsed time for each on exit"))

This class manages callbacks registration, as well as provides a way for PassInstrumentation to pass ...

void registerBeforeAnalysisCallback(CallableT C)

void registerAfterPassInvalidatedCallback(CallableT C, bool ToFront=false)

void registerAfterAnalysisCallback(CallableT C, bool ToFront=false)

void registerBeforeNonSkippedPassCallback(CallableT C)

void registerAfterPassCallback(CallableT C, bool ToFront=false)