dongjunduo updated this revision to Diff 459423.
dongjunduo added a comment.

fix related nits


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D131469/new/

https://reviews.llvm.org/D131469

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

Index: clang/tools/driver/cc1_main.cpp
===================================================================
--- clang/tools/driver/cc1_main.cpp
+++ clang/tools/driver/cc1_main.cpp
@@ -256,17 +256,10 @@
   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();
Index: clang/test/Driver/check-time-trace.cpp
===================================================================
--- clang/test/Driver/check-time-trace.cpp
+++ clang/test/Driver/check-time-trace.cpp
@@ -1,3 +1,6 @@
+// RUN: rm -rf %T/exe && mkdir %T/exe
+// RUN: %clangxx -### -ftime-trace -ftime-trace-granularity=0 -o %T/exe/check-time-trace %s 2>&1 \
+// RUN:   | FileCheck --check-prefix=CHECK-OPT %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)' \
@@ -17,6 +20,7 @@
 // RUN:   | %python -c 'import json, sys; json.dump(json.loads(sys.stdin.read()), sys.stdout, sort_keys=True, indent=2)' \
 // RUN:   | FileCheck %s
 
+// CHECK-OPT:  "-ftime-trace={{.*}}{{/|\\\\}}exe{{/|\\\\}}check-time-trace{{.*}}.json"
 // CHECK:      "beginningOfTime": {{[0-9]{16},}}
 // CHECK-NEXT: "traceEvents": [
 // CHECK:      "args":
Index: clang/lib/Driver/Driver.cpp
===================================================================
--- clang/lib/Driver/Driver.cpp
+++ clang/lib/Driver/Driver.cpp
@@ -4510,6 +4510,95 @@
   llvm_unreachable("invalid phase in ConstructPhaseAction");
 }
 
+// Infer data storing path of the options `-ftime-trace`, `-ftime-trace=<path>`
+static void inferTimeTracePath(Compilation &C) {
+  bool HasTimeTrace = C.getArgs().hasArg(options::OPT_ftime_trace);
+  bool HasTimeTraceFile = C.getArgs().hasArg(options::OPT_ftime_trace_EQ);
+  // 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());
+      SmallString<128> arg("-ftime-trace=");
+      if (!HasTimeTraceFile) {
+        if (TracePathReal.empty()) {
+          // /xxx/yyy.o => /xxx/yyy.json
+          llvm::sys::path::replace_extension(OutputPath, "json");
+          arg += OutputPath;
+        } 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 += TracePathReal;
+        }
+      } 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 += TracePathReal;
+      }
+
+      assert(arg.size() > strlen("-ftime-trace") &&
+             arg.find("-ftime-trace=") == 0 && arg[arg.size() - 1] != '=' &&
+             "invalid `-ftime-trace=<path>`");
+
+      // Replace `-ftime-trace` or `-ftime-trace=<path>` with the modified
+      // `-ftime-trace=<infered_path>`.
+      auto &JArgs = J.getArguments();
+      for (size_t I = 0, S = JArgs.size(); I < S; ++I) {
+        if (StringRef(JArgs[I]).startswith("-ftime-trace=") ||
+            (StringRef(JArgs[I]) == "-ftime-trace" && !HasTimeTraceFile)) {
+          ArgStringList NewArgs(JArgs.begin(), JArgs.begin() + I);
+          NewArgs.push_back(C.getArgs().MakeArgStringRef(arg));
+          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 +4686,9 @@
                        /*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)
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to