[llvm-branch-commits] [clang] fa45065 - [Clang] change default storing path of `-ftime-trace`

Junduo Dong via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Fri Sep 2 18:43:03 PDT 2022


Author: Junduo Dong
Date: 2022-09-02T18:41:44-07:00
New Revision: fa4506573a7f8ebc3baefce4cb83d50ad5df1109

URL: https://github.com/llvm/llvm-project/commit/fa4506573a7f8ebc3baefce4cb83d50ad5df1109
DIFF: https://github.com/llvm/llvm-project/commit/fa4506573a7f8ebc3baefce4cb83d50ad5df1109.diff

LOG: [Clang] change default storing path of `-ftime-trace`

1. This implementation change the default storing behavior of -ftime-trace only.

That is, if the compiling job contains the linking action, the executable file' s directory may be seem as the main work directory.
Thus the time trace files would be stored in the same directory of linking result.

By this approach, the user can easily get the time-trace files in the main work directory. The improved demo results:

```
$ clang++ -ftime-trace -o main.out /demo/main.cpp
$ ls .
main.out   main-[random-string].json
```

2. In addition, the main codes of time-trace files' path inference have been refactored.

* The <path> of -ftime-trace=<path> is infered in clang driver
* After that, -ftime-trace=<path> can be added into clang's options

By this approach, the dirty work of path processing and judging can be implemented in driver layer, so that the clang may focus on its main work.

 #   $ clang -ftime-trace -o xxx.out xxx.cpp

Differential Revision: https://reviews.llvm.org/D131469

Added: 
    

Modified: 
    clang/lib/Driver/Driver.cpp
    clang/test/Driver/check-time-trace.cpp
    clang/tools/driver/cc1_main.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index ba359a1d31a5..5f5655fbc34a 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -4510,6 +4510,102 @@ Action *Driver::ConstructPhaseAction(
   llvm_unreachable("invalid phase in ConstructPhaseAction");
 }
 
+// Infer data storing path of the options `-ftime-trace`, `-ftime-trace=<path>`
+void InferTimeTracePath(Compilation &C) {
+  bool HasTimeTrace =
+      C.getArgs().getLastArg(options::OPT_ftime_trace) != nullptr;
+  bool HasTimeTraceFile =
+      C.getArgs().getLastArg(options::OPT_ftime_trace_EQ) != nullptr;
+  // Whether `-ftime-trace` or `-ftime-trace=<path>` are specified
+  if (!HasTimeTrace && !HasTimeTraceFile)
+    return;
+
+  // If `-ftime-trace=<path>` is specified, TracePath is the <path>.
+  // Else if there is a linking job, TracePath is the parent path of .exe,
+  //         then the OutputFile's name may be appended to it.
+  // Else, TracePath is "",
+  //         then the full OutputFile's path may be appended to it.
+  SmallString<128> TracePath("");
+
+  if (HasTimeTraceFile) {
+    TracePath = SmallString<128>(
+        C.getArgs().getLastArg(options::OPT_ftime_trace_EQ)->getValue());
+  } else {
+    // Get linking executable file's parent path as TracePath's parent path,
+    // default is ".". Filename may be determined and added into TracePath then.
+    //
+    // e.g. executable file's path: /usr/local/a.out
+    //      its parent's path:      /usr/local
+    for (auto &J : C.getJobs()) {
+      if (J.getSource().getKind() == Action::LinkJobClass) {
+        assert(!J.getOutputFilenames().empty() &&
+               "linking output filename is empty");
+        auto OutputFilePath =
+            SmallString<128>(J.getOutputFilenames()[0].c_str());
+        if (llvm::sys::path::has_parent_path(OutputFilePath)) {
+          TracePath = llvm::sys::path::parent_path(OutputFilePath);
+        } else {
+          TracePath = SmallString<128>(".");
+        }
+        break;
+      }
+    }
+  }
+
+  // Add or replace the modified -ftime-trace=<path>` to all clang jobs
+  for (auto &J : C.getJobs()) {
+    if (J.getSource().getKind() == Action::AssembleJobClass ||
+        J.getSource().getKind() == Action::BackendJobClass ||
+        J.getSource().getKind() == Action::CompileJobClass) {
+      SmallString<128> TracePathReal = TracePath;
+      SmallString<128> OutputPath(J.getOutputFilenames()[0].c_str());
+      std::string arg = std::string("-ftime-trace=");
+      if (!HasTimeTraceFile) {
+        if (TracePathReal.empty()) {
+          // /xxx/yyy.o => /xxx/yyy.json
+          llvm::sys::path::replace_extension(OutputPath, "json");
+          arg += std::string(OutputPath.c_str());
+        } else {
+          // /xxx/yyy.o => /executable_file_parent_path/yyy.json
+          llvm::sys::path::append(TracePathReal,
+                                  llvm::sys::path::filename(OutputPath));
+          llvm::sys::path::replace_extension(TracePathReal, "json");
+          arg += std::string(TracePathReal.c_str());
+        }
+      } else {
+        // /full_file_path_specified or /path_specified/yyy.json
+        if (llvm::sys::fs::is_directory(TracePathReal))
+          llvm::sys::path::append(TracePathReal,
+                                  llvm::sys::path::filename(OutputPath));
+        llvm::sys::path::replace_extension(TracePathReal, "json");
+        arg += std::string(TracePathReal.c_str());
+      }
+
+      assert(arg.size() > strlen("-ftime-trace") &&
+             arg.find("-ftime-trace=") == 0 && arg[arg.size() - 1] != '=' &&
+             "invalid `-ftime-trace=<path>`");
+
+      const std::string::size_type size = arg.size();
+      char *buffer = new char[size + 1];
+      memcpy(buffer, arg.c_str(), size + 1);
+
+      // Replace `-ftime-trace` or `-ftime-trace=<path>` with the modified
+      // `-ftime-trace=<infered_path>`.
+      auto &JArgs = J.getArguments();
+      for (unsigned I = 0; I < JArgs.size(); ++I) {
+        if (StringRef(JArgs[I]).startswith("-ftime-trace=") ||
+            (StringRef(JArgs[I]).equals("-ftime-trace") && !HasTimeTraceFile)) {
+          ArgStringList NewArgs(JArgs.begin(), JArgs.begin() + I);
+          NewArgs.push_back(buffer);
+          NewArgs.append(JArgs.begin() + I + 1, JArgs.end());
+          J.replaceArguments(NewArgs);
+          break;
+        }
+      }
+    }
+  }
+}
+
 void Driver::BuildJobs(Compilation &C) const {
   llvm::PrettyStackTraceString CrashInfo("Building compilation jobs");
 
@@ -4597,6 +4693,9 @@ void Driver::BuildJobs(Compilation &C) const {
                        /*TargetDeviceOffloadKind*/ Action::OFK_None);
   }
 
+  // set data storing path of the options `-ftime-trace`, `-ftime-trace=<path>`
+  InferTimeTracePath(C);
+
   // If we have more than one job, then disable integrated-cc1 for now. Do this
   // also when we need to report process execution statistics.
   if (C.getJobs().size() > 1 || CCPrintProcessStats)

diff  --git a/clang/test/Driver/check-time-trace.cpp b/clang/test/Driver/check-time-trace.cpp
index 52b3e71394fb..e0d1e935a733 100644
--- a/clang/test/Driver/check-time-trace.cpp
+++ b/clang/test/Driver/check-time-trace.cpp
@@ -1,3 +1,8 @@
+// RUN: rm -rf %T/exe && mkdir %T/exe
+// RUN: %clangxx -ftime-trace -ftime-trace-granularity=0 -o %T/exe/check-time-trace %s
+// RUN: cat %T/exe/check-time-trace*.json \
+// RUN:   | %python -c 'import json, sys; json.dump(json.loads(sys.stdin.read()), sys.stdout, sort_keys=True, indent=2)' \
+// RUN:   | FileCheck %s
 // RUN: %clangxx -S -ftime-trace -ftime-trace-granularity=0 -o %T/check-time-trace %s
 // RUN: cat %T/check-time-trace.json \
 // RUN:   | %python -c 'import json, sys; json.dump(json.loads(sys.stdin.read()), sys.stdout, sort_keys=True, indent=2)' \

diff  --git a/clang/tools/driver/cc1_main.cpp b/clang/tools/driver/cc1_main.cpp
index de33aa9ea934..5da37577a100 100644
--- a/clang/tools/driver/cc1_main.cpp
+++ b/clang/tools/driver/cc1_main.cpp
@@ -256,17 +256,10 @@ int cc1_main(ArrayRef<const char *> Argv, const char *Argv0, void *MainAddr) {
   llvm::TimerGroup::clearAll();
 
   if (llvm::timeTraceProfilerEnabled()) {
-    SmallString<128> Path(Clang->getFrontendOpts().OutputFile);
-    llvm::sys::path::replace_extension(Path, "json");
-    if (!Clang->getFrontendOpts().TimeTracePath.empty()) {
-      // replace the suffix to '.json' directly
-      SmallString<128> TracePath(Clang->getFrontendOpts().TimeTracePath);
-      if (llvm::sys::fs::is_directory(TracePath))
-        llvm::sys::path::append(TracePath, llvm::sys::path::filename(Path));
-      Path.assign(TracePath);
-    }
+    SmallString<128> TracePath(Clang->getFrontendOpts().TimeTracePath);
+    assert(!TracePath.empty() && "`-ftime-trace=<path>` is empty");
     if (auto profilerOutput = Clang->createOutputFile(
-            Path.str(), /*Binary=*/false, /*RemoveFileOnSignal=*/false,
+            TracePath.str(), /*Binary=*/false, /*RemoveFileOnSignal=*/false,
             /*useTemporary=*/false)) {
       llvm::timeTraceProfilerWrite(*profilerOutput);
       profilerOutput.reset();


        


More information about the llvm-branch-commits mailing list