Skip to content

[TableGen] Factor out timer code into a new TGTimer class #111054

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 1 commit into from
Oct 4, 2024
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
40 changes: 7 additions & 33 deletions llvm/include/llvm/TableGen/Record.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ class RecordVal;
class Resolver;
class StringInit;
class TypedInit;
class TGTimer;

//===----------------------------------------------------------------------===//
// Type Classes
Expand Down Expand Up @@ -1785,11 +1786,13 @@ class Record {
}

RecordVal *getValue(const Init *Name) {
return const_cast<RecordVal *>(static_cast<const Record *>(this)->getValue(Name));
return const_cast<RecordVal *>(
static_cast<const Record *>(this)->getValue(Name));
}

RecordVal *getValue(StringRef Name) {
return const_cast<RecordVal *>(static_cast<const Record *>(this)->getValue(Name));
return const_cast<RecordVal *>(
static_cast<const Record *>(this)->getValue(Name));
}

void addTemplateArg(Init *Name) {
Expand Down Expand Up @@ -2033,29 +2036,7 @@ class RecordKeeper {

Init *getNewAnonymousName();

/// Start phase timing; called if the --time-phases option is specified.
void startPhaseTiming() {
TimingGroup = new TimerGroup("TableGen", "TableGen Phase Timing");
}

/// Start timing a phase. Automatically stops any previous phase timer.
void startTimer(StringRef Name) const;

/// Stop timing a phase.
void stopTimer();

/// Start timing the overall backend. If the backend itself starts a timer,
/// then this timer is cleared.
void startBackendTimer(StringRef Name);

/// Stop timing the overall backend.
void stopBackendTimer();

/// Stop phase timing and print the report.
void stopPhaseTiming() {
if (TimingGroup)
delete TimingGroup;
}
TGTimer &getTimer() const { return *Timer; }

//===--------------------------------------------------------------------===//
// High-level helper methods, useful for tablegen backends.
Expand Down Expand Up @@ -2089,16 +2070,9 @@ class RecordKeeper {
mutable std::map<std::string, std::vector<const Record *>> Cache;
GlobalMap ExtraGlobals;

// TODO: Move timing related code out of RecordKeeper.
// These members are for the phase timing feature. We need a timer group,
// the last timer started, and a flag to say whether the last timer
// is the special "backend overall timer."
mutable TimerGroup *TimingGroup = nullptr;
mutable Timer *LastTimer = nullptr;
mutable bool BackendTimer = false;

/// The internal uniquer implementation of the RecordKeeper.
std::unique_ptr<detail::RecordKeeperImpl> Impl;
std::unique_ptr<TGTimer> Timer;
};

/// Sorting predicate to sort record pointers by name.
Expand Down
59 changes: 59 additions & 0 deletions llvm/include/llvm/TableGen/TGTimer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
//===- llvm/TableGen/TGTimer.h - Class for TableGen Timer -------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file defines the TableGen timer class. It's a thin wrapper around timer
// support in llvm/Support/Timer.h.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_TABLEGEN_TGTIMER_H
#define LLVM_TABLEGEN_TGTIMER_H

#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Timer.h"
#include <memory>

namespace llvm {

// Timer related functionality f or TableGen backends.
class TGTimer {
private:
std::unique_ptr<TimerGroup> TimingGroup;
std::unique_ptr<Timer> LastTimer;
bool BackendTimer = false; // Is last timer special backend overall timer?

public:
TGTimer() = default;
~TGTimer() = default;

/// Start phase timing; called if the --time-phases option is specified.
void startPhaseTiming() {
TimingGroup =
std::make_unique<TimerGroup>("TableGen", "TableGen Phase Timing");
}

/// Start timing a phase. Automatically stops any previous phase timer.
void startTimer(StringRef Name);

/// Stop timing a phase.
void stopTimer();

/// Start timing the overall backend. If the backend itself starts a timer,
/// then this timer is cleared.
void startBackendTimer(StringRef Name);

/// Stop timing the overall backend.
void stopBackendTimer();

/// Stop phase timing and print the report.
void stopPhaseTiming() { TimingGroup.reset(); }
};

} // end namespace llvm

#endif // LLVM_TABLEGEN_TGTIMER_H
1 change: 1 addition & 0 deletions llvm/lib/TableGen/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ add_llvm_component_library(LLVMTableGen
TableGenBackendSkeleton.cpp
TGLexer.cpp
TGParser.cpp
TGTimer.cpp

ADDITIONAL_HEADER_DIRS
${LLVM_MAIN_INCLUDE_DIR}/llvm/TableGen
Expand Down
20 changes: 11 additions & 9 deletions llvm/lib/TableGen/Main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include "llvm/Support/raw_ostream.h"
#include "llvm/TableGen/Error.h"
#include "llvm/TableGen/Record.h"
#include "llvm/TableGen/TGTimer.h"
#include "llvm/TableGen/TableGenBackend.h"
#include <memory>
#include <string>
Expand Down Expand Up @@ -98,13 +99,14 @@ static int createDependencyFile(const TGParser &Parser, const char *argv0) {
int llvm::TableGenMain(const char *argv0,
std::function<TableGenMainFn> MainFn) {
RecordKeeper Records;
TGTimer &Timer = Records.getTimer();

if (TimePhases)
Records.startPhaseTiming();
Timer.startPhaseTiming();

// Parse the input file.

Records.startTimer("Parse, build records");
Timer.startTimer("Parse, build records");
ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr =
MemoryBuffer::getFileOrSTDIN(InputFilename, /*IsText=*/true);
if (std::error_code EC = FileOrErr.getError())
Expand All @@ -124,18 +126,18 @@ int llvm::TableGenMain(const char *argv0,

if (Parser.ParseFile())
return 1;
Records.stopTimer();
Timer.stopTimer();

// Write output to memory.
Records.startBackendTimer("Backend overall");
Timer.startBackendTimer("Backend overall");
std::string OutString;
raw_string_ostream Out(OutString);
unsigned status = 0;
// ApplyCallback will return true if it did not apply any callback. In that
// case, attempt to apply the MainFn.
if (TableGen::Emitter::ApplyCallback(Records, Out))
status = MainFn ? MainFn(Out, Records) : 1;
Records.stopBackendTimer();
Timer.stopBackendTimer();
if (status)
return 1;

Expand All @@ -148,7 +150,7 @@ int llvm::TableGenMain(const char *argv0,
return Ret;
}

Records.startTimer("Write output");
Timer.startTimer("Write output");
bool WriteFile = true;
if (WriteIfChanged) {
// Only updates the real output file if there are any differences.
Expand All @@ -169,9 +171,9 @@ int llvm::TableGenMain(const char *argv0,
if (ErrorsPrinted == 0)
OutFile.keep();
}
Records.stopTimer();
Records.stopPhaseTiming();

Timer.stopTimer();
Timer.stopPhaseTiming();

if (ErrorsPrinted > 0)
return reportError(argv0, Twine(ErrorsPrinted) + " errors.\n");
Expand Down
46 changes: 4 additions & 42 deletions llvm/lib/TableGen/Record.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include "llvm/Support/SMLoc.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/TableGen/Error.h"
#include "llvm/TableGen/TGTimer.h"
#include <cassert>
#include <cstdint>
#include <map>
Expand Down Expand Up @@ -3218,7 +3219,9 @@ void Record::checkUnusedTemplateArgs() {
}

RecordKeeper::RecordKeeper()
: Impl(std::make_unique<detail::RecordKeeperImpl>(*this)) {}
: Impl(std::make_unique<detail::RecordKeeperImpl>(*this)),
Timer(std::make_unique<TGTimer>()) {}

RecordKeeper::~RecordKeeper() = default;

#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
Expand All @@ -3242,47 +3245,6 @@ Init *RecordKeeper::getNewAnonymousName() {
return AnonymousNameInit::get(*this, getImpl().AnonCounter++);
}

// These functions implement the phase timing facility. Starting a timer
// when one is already running stops the running one.

void RecordKeeper::startTimer(StringRef Name) const {
if (TimingGroup) {
if (LastTimer && LastTimer->isRunning()) {
LastTimer->stopTimer();
if (BackendTimer) {
LastTimer->clear();
BackendTimer = false;
}
}

LastTimer = new Timer("", Name, *TimingGroup);
LastTimer->startTimer();
}
}

void RecordKeeper::stopTimer() {
if (TimingGroup) {
assert(LastTimer && "No phase timer was started");
LastTimer->stopTimer();
}
}

void RecordKeeper::startBackendTimer(StringRef Name) {
if (TimingGroup) {
startTimer(Name);
BackendTimer = true;
}
}

void RecordKeeper::stopBackendTimer() {
if (TimingGroup) {
if (BackendTimer) {
stopTimer();
BackendTimer = false;
}
}
}

ArrayRef<const Record *>
RecordKeeper::getAllDerivedDefinitions(StringRef ClassName) const {
// We cache the record vectors for single classes. Many backends request
Expand Down
54 changes: 54 additions & 0 deletions llvm/lib/TableGen/TGTimer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
//===- TGTimer.cpp - TableGen Timer implementation --------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// Implement the tablegen timer class.
//
//===----------------------------------------------------------------------===//

#include "llvm/TableGen/TGTimer.h"
using namespace llvm;

// These functions implement the phase timing facility. Starting a timer
// when one is already running stops the running one.
void TGTimer::startTimer(StringRef Name) {
if (!TimingGroup)
return;
if (LastTimer && LastTimer->isRunning()) {
LastTimer->stopTimer();
if (BackendTimer) {
LastTimer->clear();
BackendTimer = false;
}
}

LastTimer = std::make_unique<Timer>("", Name, *TimingGroup);
LastTimer->startTimer();
}

void TGTimer::stopTimer() {
if (!TimingGroup)
return;

assert(LastTimer && "No phase timer was started");
LastTimer->stopTimer();
}

void TGTimer::startBackendTimer(StringRef Name) {
if (!TimingGroup)
return;

startTimer(Name);
BackendTimer = true;
}

void TGTimer::stopBackendTimer() {
if (!TimingGroup || !BackendTimer)
return;
stopTimer();
BackendTimer = false;
}
5 changes: 3 additions & 2 deletions llvm/utils/TableGen/CallingConvEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "Common/CodeGenTarget.h"
#include "llvm/TableGen/Error.h"
#include "llvm/TableGen/Record.h"
#include "llvm/TableGen/TGTimer.h"
#include "llvm/TableGen/TableGenBackend.h"
#include <deque>
#include <set>
Expand Down Expand Up @@ -51,7 +52,7 @@ void CallingConvEmitter::run(raw_ostream &O) {

// Emit prototypes for all of the non-custom CC's so that they can forward ref
// each other.
Records.startTimer("Emit prototypes");
Records.getTimer().startTimer("Emit prototypes");
O << "#ifndef GET_CC_REGISTER_LISTS\n\n";
for (const Record *CC : CCs) {
if (!CC->getValueAsBit("Custom")) {
Expand All @@ -71,7 +72,7 @@ void CallingConvEmitter::run(raw_ostream &O) {
}

// Emit each non-custom calling convention description in full.
Records.startTimer("Emit full descriptions");
Records.getTimer().startTimer("Emit full descriptions");
for (const Record *CC : CCs) {
if (!CC->getValueAsBit("Custom")) {
EmitCallingConv(CC, O);
Expand Down
Loading
Loading