[llvm-rtdyld] Add timers to match llvm-jitlink.
authorLang Hames <lhames@gmail.com>
Wed, 4 Sep 2019 20:26:25 +0000 (20:26 +0000)
committerLang Hames <lhames@gmail.com>
Wed, 4 Sep 2019 20:26:25 +0000 (20:26 +0000)
When using llvm-rtdyld to execute code, -show-times will now show the time
taken to load the object files, apply relocations, and execute the
rtdyld-linked code.

llvm-svn: 370968

llvm/tools/llvm-jitlink/llvm-jitlink.cpp
llvm/tools/llvm-rtdyld/llvm-rtdyld.cpp

index 651e312..6dbd846 100644 (file)
@@ -612,8 +612,8 @@ Expected<int> runEntryPoint(Session &S, JITEvaluatedSymbol EntryPoint) {
 struct JITLinkTimers {
   TimerGroup JITLinkTimers{"llvm-jitlink timers",
                            "timers for llvm-jitlink phases"};
-  Timer LoadObjectsTimer{
-      "load", "time to load/add object files to llvm-jitlink", JITLinkTimers};
+  Timer LoadObjectsTimer{"load", "time to load/add object files",
+                         JITLinkTimers};
   Timer LinkTimer{"link", "time to link object files", JITLinkTimers};
   Timer RunTimer{"run", "time to execute jitlink'd code", JITLinkTimers};
 };
index af83ea1..e7820bc 100644 (file)
 #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,22 @@ 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 RTDyldTimers{"llvm-rtdyld timers",
+                          "timers for llvm-rtdyld phases"};
+  Timer LoadObjectsTimer{"load", "time to load/add object files", RTDyldTimers};
+  Timer LinkTimer{"link", "time to link object files", RTDyldTimers};
+  Timer RunTimer{"run", "time to execute jitlink'd code", RTDyldTimers};
+};
+
+std::unique_ptr<RTDyldTimers> Timers;
+
 /* *** */
 
 using SectionIDMap = StringMap<unsigned>;
@@ -489,35 +504,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);
@@ -549,7 +570,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) {
@@ -935,16 +962,27 @@ 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;
   }
 }