[llvm] [tools] LLVM Advisor - optimization analysis and performance guidance tool (PR #147451)

Miguel Cárdenas via llvm-commits llvm-commits at lists.llvm.org
Sat Jul 12 20:48:32 PDT 2025


https://github.com/miguelcsx updated https://github.com/llvm/llvm-project/pull/147451

>From 429ae143a09775ea9e5ab8854b9b695edd7cf63f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Miguel=20C=C3=A1rdenas?= <miguelecsx at gmail.com>
Date: Tue, 8 Jul 2025 04:41:10 +0200
Subject: [PATCH] [llvm-advisor] add initial project structure and
 configuration

The AdvisorConfig class provides JSON based configuration loading
with file classification patterns and output directory management.
---
 llvm/tools/llvm-advisor/CMakeLists.txt        | 15 +++++
 llvm/tools/llvm-advisor/config/config.json    |  7 ++
 llvm/tools/llvm-advisor/src/CMakeLists.txt    | 35 ++++++++++
 .../llvm-advisor/src/Config/AdvisorConfig.cpp | 64 +++++++++++++++++++
 .../llvm-advisor/src/Config/AdvisorConfig.h   | 41 ++++++++++++
 5 files changed, 162 insertions(+)
 create mode 100644 llvm/tools/llvm-advisor/CMakeLists.txt
 create mode 100644 llvm/tools/llvm-advisor/config/config.json
 create mode 100644 llvm/tools/llvm-advisor/src/CMakeLists.txt
 create mode 100644 llvm/tools/llvm-advisor/src/Config/AdvisorConfig.cpp
 create mode 100644 llvm/tools/llvm-advisor/src/Config/AdvisorConfig.h

diff --git a/llvm/tools/llvm-advisor/CMakeLists.txt b/llvm/tools/llvm-advisor/CMakeLists.txt
new file mode 100644
index 0000000000000..d2389bdd1e0fa
--- /dev/null
+++ b/llvm/tools/llvm-advisor/CMakeLists.txt
@@ -0,0 +1,15 @@
+cmake_minimum_required(VERSION 3.18)
+
+set(LLVM_TOOL_LLVM_ADVISOR_BUILD_DEFAULT ON)
+set(LLVM_REQUIRE_EXE_NAMES llvm-advisor)
+
+add_subdirectory(src)
+
+# Set the executable name
+set_target_properties(llvm-advisor PROPERTIES
+  OUTPUT_NAME llvm-advisor)
+
+# Install the binary
+install(TARGETS llvm-advisor
+  RUNTIME DESTINATION bin
+  COMPONENT llvm-advisor)
diff --git a/llvm/tools/llvm-advisor/config/config.json b/llvm/tools/llvm-advisor/config/config.json
new file mode 100644
index 0000000000000..9e94a41ff46c4
--- /dev/null
+++ b/llvm/tools/llvm-advisor/config/config.json
@@ -0,0 +1,7 @@
+{
+  "outputDir": ".llvm-advisor",
+  "verbose": false,
+  "keepTemps": false,
+  "runProfiler": true,
+  "timeout": 60
+}
diff --git a/llvm/tools/llvm-advisor/src/CMakeLists.txt b/llvm/tools/llvm-advisor/src/CMakeLists.txt
new file mode 100644
index 0000000000000..81088f8231625
--- /dev/null
+++ b/llvm/tools/llvm-advisor/src/CMakeLists.txt
@@ -0,0 +1,35 @@
+# Gather all .cpp sources in this directory tree
+file(GLOB_RECURSE LLVM_ADVISOR_SOURCES CONFIGURE_DEPENDS
+  ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp
+)
+
+# Define the executable target
+add_llvm_tool(llvm-advisor
+  ${LLVM_ADVISOR_SOURCES}
+)
+
+# Link required LLVM libraries
+target_link_libraries(llvm-advisor PRIVATE
+  LLVMSupport
+  LLVMCore
+  LLVMIRReader
+  LLVMBitWriter
+  LLVMRemarks
+  LLVMProfileData
+)
+
+# Set include directories
+target_include_directories(llvm-advisor PRIVATE
+  ${CMAKE_CURRENT_SOURCE_DIR}
+)
+
+# Install the Python view module alongside the binary
+install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../view/
+  DESTINATION ${CMAKE_INSTALL_BINDIR}/view
+  FILES_MATCHING
+  PATTERN "*.py"
+  PATTERN "*.html"
+  PATTERN "*.css"
+  PATTERN "*.js"
+  PATTERN "*.md"
+)
diff --git a/llvm/tools/llvm-advisor/src/Config/AdvisorConfig.cpp b/llvm/tools/llvm-advisor/src/Config/AdvisorConfig.cpp
new file mode 100644
index 0000000000000..69f1e3d52702e
--- /dev/null
+++ b/llvm/tools/llvm-advisor/src/Config/AdvisorConfig.cpp
@@ -0,0 +1,64 @@
+#include "AdvisorConfig.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/JSON.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/Path.h"
+
+namespace llvm {
+namespace advisor {
+
+AdvisorConfig::AdvisorConfig() {
+  // Use relative path as default, will be resolved by CompilationManager
+  OutputDir_ = ".llvm-advisor";
+}
+
+Expected<bool> AdvisorConfig::loadFromFile(const std::string &path) {
+  auto BufferOrError = MemoryBuffer::getFile(path);
+  if (!BufferOrError) {
+    return createStringError(BufferOrError.getError(),
+                             "Cannot read config file");
+  }
+
+  auto Buffer = std::move(*BufferOrError);
+  Expected<json::Value> JsonOrError = json::parse(Buffer->getBuffer());
+  if (!JsonOrError) {
+    return JsonOrError.takeError();
+  }
+
+  auto &Json = *JsonOrError;
+  auto *Obj = Json.getAsObject();
+  if (!Obj) {
+    return createStringError(std::make_error_code(std::errc::invalid_argument),
+                             "Config file must contain JSON object");
+  }
+
+  if (auto outputDirOpt = Obj->getString("outputDir"); outputDirOpt) {
+    OutputDir_ = outputDirOpt->str();
+  }
+
+  if (auto verboseOpt = Obj->getBoolean("verbose"); verboseOpt) {
+    Verbose_ = *verboseOpt;
+  }
+
+  if (auto keepTempsOpt = Obj->getBoolean("keepTemps"); keepTempsOpt) {
+    KeepTemps_ = *keepTempsOpt;
+  }
+
+  if (auto runProfileOpt = Obj->getBoolean("runProfiler"); runProfileOpt) {
+    RunProfiler_ = *runProfileOpt;
+  }
+
+  if (auto timeoutOpt = Obj->getInteger("timeout"); timeoutOpt) {
+    TimeoutSeconds_ = static_cast<int>(*timeoutOpt);
+  }
+
+  return true;
+}
+
+std::string AdvisorConfig::getToolPath(const std::string &tool) const {
+  // For now, just return the tool name and rely on PATH
+  return tool;
+}
+
+} // namespace advisor
+} // namespace llvm
diff --git a/llvm/tools/llvm-advisor/src/Config/AdvisorConfig.h b/llvm/tools/llvm-advisor/src/Config/AdvisorConfig.h
new file mode 100644
index 0000000000000..b7f553fddbb23
--- /dev/null
+++ b/llvm/tools/llvm-advisor/src/Config/AdvisorConfig.h
@@ -0,0 +1,41 @@
+#ifndef LLVM_ADVISOR_CONFIG_H
+#define LLVM_ADVISOR_CONFIG_H
+
+#include "llvm/Support/Error.h"
+#include <string>
+
+namespace llvm {
+namespace advisor {
+
+class AdvisorConfig {
+public:
+  AdvisorConfig();
+
+  Expected<bool> loadFromFile(const std::string &path);
+
+  void setOutputDir(const std::string &dir) { OutputDir_ = dir; }
+  void setVerbose(bool verbose) { Verbose_ = verbose; }
+  void setKeepTemps(bool keep) { KeepTemps_ = keep; }
+  void setRunProfiler(bool run) { RunProfiler_ = run; }
+  void setTimeout(int seconds) { TimeoutSeconds_ = seconds; }
+
+  const std::string &getOutputDir() const { return OutputDir_; }
+  bool getVerbose() const { return Verbose_; }
+  bool getKeepTemps() const { return KeepTemps_; }
+  bool getRunProfiler() const { return RunProfiler_; }
+  int getTimeout() const { return TimeoutSeconds_; }
+
+  std::string getToolPath(const std::string &tool) const;
+
+private:
+  std::string OutputDir_;
+  bool Verbose_ = false;
+  bool KeepTemps_ = false;
+  bool RunProfiler_ = true;
+  int TimeoutSeconds_ = 60;
+};
+
+} // namespace advisor
+} // namespace llvm
+
+#endif



More information about the llvm-commits mailing list