aboutsummaryrefslogtreecommitdiff
path: root/tools/llvm-rtdyld/llvm-rtdyld.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tools/llvm-rtdyld/llvm-rtdyld.cpp')
-rw-r--r--tools/llvm-rtdyld/llvm-rtdyld.cpp104
1 files changed, 70 insertions, 34 deletions
diff --git a/tools/llvm-rtdyld/llvm-rtdyld.cpp b/tools/llvm-rtdyld/llvm-rtdyld.cpp
index a7cc1deb8cf6..3a36e7709483 100644
--- a/tools/llvm-rtdyld/llvm-rtdyld.cpp
+++ b/tools/llvm-rtdyld/llvm-rtdyld.cpp
@@ -27,12 +27,13 @@
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/DynamicLibrary.h"
#include "llvm/Support/InitLLVM.h"
+#include "llvm/Support/MSVCErrorWorkarounds.h"
#include "llvm/Support/Memory.h"
#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/MSVCErrorWorkarounds.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/TargetSelect.h"
+#include "llvm/Support/Timer.h"
#include "llvm/Support/raw_ostream.h"
#include <future>
@@ -138,8 +139,21 @@ PrintAllocationRequests("print-alloc-requests",
"manager by RuntimeDyld"),
cl::Hidden);
+static cl::opt<bool> ShowTimes("show-times",
+ cl::desc("Show times for llvm-rtdyld phases"),
+ cl::init(false));
+
ExitOnError ExitOnErr;
+struct RTDyldTimers {
+ TimerGroup RTDyldTG{"llvm-rtdyld timers", "timers for llvm-rtdyld phases"};
+ Timer LoadObjectsTimer{"load", "time to load/add object files", RTDyldTG};
+ Timer LinkTimer{"link", "time to link object files", RTDyldTG};
+ Timer RunTimer{"run", "time to execute jitlink'd code", RTDyldTG};
+};
+
+std::unique_ptr<RTDyldTimers> Timers;
+
/* *** */
using SectionIDMap = StringMap<unsigned>;
@@ -441,8 +455,6 @@ static int printLineInfoForInput(bool LoadObjects, bool UseDebugObj) {
continue;
}
object::section_iterator Sec = *SecOrErr;
- StringRef SecName;
- Sec->getName(SecName);
Address.SectionIndex = Sec->getIndex();
uint64_t SectionLoadAddress =
LoadedObjInfo->getSectionLoadAddress(*Sec);
@@ -491,35 +503,41 @@ static int executeInput() {
// If we don't have any input files, read from stdin.
if (!InputFileList.size())
InputFileList.push_back("-");
- for (auto &File : InputFileList) {
- // Load the input memory buffer.
- ErrorOr<std::unique_ptr<MemoryBuffer>> InputBuffer =
- MemoryBuffer::getFileOrSTDIN(File);
- if (std::error_code EC = InputBuffer.getError())
- ErrorAndExit("unable to read input: '" + EC.message() + "'");
- Expected<std::unique_ptr<ObjectFile>> MaybeObj(
- ObjectFile::createObjectFile((*InputBuffer)->getMemBufferRef()));
-
- if (!MaybeObj) {
- std::string Buf;
- raw_string_ostream OS(Buf);
- logAllUnhandledErrors(MaybeObj.takeError(), OS);
- OS.flush();
- ErrorAndExit("unable to create object file: '" + Buf + "'");
- }
+ {
+ TimeRegion TR(Timers ? &Timers->LoadObjectsTimer : nullptr);
+ for (auto &File : InputFileList) {
+ // Load the input memory buffer.
+ ErrorOr<std::unique_ptr<MemoryBuffer>> InputBuffer =
+ MemoryBuffer::getFileOrSTDIN(File);
+ if (std::error_code EC = InputBuffer.getError())
+ ErrorAndExit("unable to read input: '" + EC.message() + "'");
+ Expected<std::unique_ptr<ObjectFile>> MaybeObj(
+ ObjectFile::createObjectFile((*InputBuffer)->getMemBufferRef()));
+
+ if (!MaybeObj) {
+ std::string Buf;
+ raw_string_ostream OS(Buf);
+ logAllUnhandledErrors(MaybeObj.takeError(), OS);
+ OS.flush();
+ ErrorAndExit("unable to create object file: '" + Buf + "'");
+ }
- ObjectFile &Obj = **MaybeObj;
+ ObjectFile &Obj = **MaybeObj;
- // Load the object file
- Dyld.loadObject(Obj);
- if (Dyld.hasError()) {
- ErrorAndExit(Dyld.getErrorString());
+ // Load the object file
+ Dyld.loadObject(Obj);
+ if (Dyld.hasError()) {
+ ErrorAndExit(Dyld.getErrorString());
+ }
}
}
- // Resove all the relocations we can.
- // FIXME: Error out if there are unresolved relocations.
- Dyld.resolveRelocations();
+ {
+ TimeRegion TR(Timers ? &Timers->LinkTimer : nullptr);
+ // Resove all the relocations we can.
+ // FIXME: Error out if there are unresolved relocations.
+ Dyld.resolveRelocations();
+ }
// Get the address of the entry point (_main by default).
void *MainAddress = Dyld.getSymbolLocalAddress(EntryPoint);
@@ -551,7 +569,13 @@ static int executeInput() {
for (auto &Arg : InputArgv)
Argv.push_back(Arg.data());
Argv.push_back(nullptr);
- return Main(Argv.size() - 1, Argv.data());
+ int Result = 0;
+ {
+ TimeRegion TR(Timers ? &Timers->RunTimer : nullptr);
+ Result = Main(Argv.size() - 1, Argv.data());
+ }
+
+ return Result;
}
static int checkAllExpressions(RuntimeDyldChecker &Checker) {
@@ -891,7 +915,7 @@ static int linkAndVerify() {
ObjectFile &Obj = **MaybeObj;
if (!Checker)
- Checker = llvm::make_unique<RuntimeDyldChecker>(
+ Checker = std::make_unique<RuntimeDyldChecker>(
IsSymbolValid, GetSymbolInfo, GetSectionInfo, GetStubInfo,
GetStubInfo, Obj.isLittleEndian() ? support::little : support::big,
Disassembler.get(), InstPrinter.get(), dbgs());
@@ -937,16 +961,28 @@ int main(int argc, char **argv) {
ExitOnErr.setBanner(std::string(argv[0]) + ": ");
+ Timers = ShowTimes ? std::make_unique<RTDyldTimers>() : nullptr;
+
+ int Result;
switch (Action) {
case AC_Execute:
- return executeInput();
+ Result = executeInput();
+ break;
case AC_PrintDebugLineInfo:
- return printLineInfoForInput(/* LoadObjects */ true,/* UseDebugObj */ true);
+ Result =
+ printLineInfoForInput(/* LoadObjects */ true, /* UseDebugObj */ true);
+ break;
case AC_PrintLineInfo:
- return printLineInfoForInput(/* LoadObjects */ true,/* UseDebugObj */false);
+ Result =
+ printLineInfoForInput(/* LoadObjects */ true, /* UseDebugObj */ false);
+ break;
case AC_PrintObjectLineInfo:
- return printLineInfoForInput(/* LoadObjects */false,/* UseDebugObj */false);
+ Result =
+ printLineInfoForInput(/* LoadObjects */ false, /* UseDebugObj */ false);
+ break;
case AC_Verify:
- return linkAndVerify();
+ Result = linkAndVerify();
+ break;
}
+ return Result;
}