Add version method and init helper (#11627)

Create helper to initialize while setting debug message and version info. Version is not embedded by default. Follow up will add option to easily create from GitHub rev.

Fixes #11574

Co-authored-by: Geoffrey Martin-Noble <gcmn@google.com>
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 6fc1369..6f3aaae 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -67,6 +67,7 @@
 set(IREE_RELEASE_PACKAGE_SUFFIX "" CACHE STRING "Suffix to append to distributed package names")
 set(IREE_RELEASE_VERSION "0.1a1" CACHE STRING "Version to embed in distributed packages")
 set(IREE_RELEASE_REVISION "HEAD" CACHE STRING "Version control revision information to embed in distributed packages")
+option(IREE_EMBED_RELEASE_INFO "Embed the IREE version information in built artifacts." OFF)
 
 option(IREE_BUILD_BINDINGS_TFLITE "Builds the IREE TFLite C API compatibility shim" ON)
 option(IREE_BUILD_BINDINGS_TFLITE_JAVA "Builds the IREE TFLite Java bindings with the C API compatibility shim" ON)
diff --git a/compiler/src/iree/compiler/Tools/BUILD b/compiler/src/iree/compiler/Tools/BUILD
index c1268a7..a79662a 100644
--- a/compiler/src/iree/compiler/Tools/BUILD
+++ b/compiler/src/iree/compiler/Tools/BUILD
@@ -4,12 +4,27 @@
 # See https://llvm.org/LICENSE.txt for license information.
 # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 
+load("@bazel_skylib//rules:common_settings.bzl", "bool_flag")
+load("//build_tools/bazel:build_defs.oss.bzl", "iree_compiler_cc_library")
+
 package(
     default_visibility = ["//visibility:public"],
     features = ["layering_check"],
     licenses = ["notice"],  # Apache 2.0
 )
 
+bool_flag(
+    name = "IREE_EMBEDDED_RELEASE_INFO",
+    build_setting_default = False,
+)
+
+config_setting(
+    name = "embedding_enabled",
+    flag_values = {
+        ":IREE_EMBEDDED_RELEASE_INFO": "True",
+    },
+)
+
 cc_library(
     name = "init_input_passes_and_dialects",
     srcs = [
@@ -36,6 +51,20 @@
     ],
 )
 
+iree_compiler_cc_library(
+    name = "init_iree",
+    srcs = [
+        "init_iree.cc",
+    ],
+    hdrs = [
+        "init_iree.h",
+    ],
+    deps = [
+        ":version",
+        "@llvm-project//llvm:Support",
+    ],
+)
+
 cc_library(
     name = "init_iree_passes_and_dialects",
     hdrs = [
@@ -182,9 +211,23 @@
     ],
     hdrs = ["iree_compile_lib.h"],
     deps = [
+        ":init_iree",
         "//compiler/src/iree/compiler/API2:Headers",
         "//compiler/src/iree/compiler/API2/Internal:Embed",
         "//compiler/src/iree/compiler/Pipelines",
         "@llvm-project//llvm:Support",
     ],
 )
+
+iree_compiler_cc_library(
+    name = "version",
+    srcs = ["version.cc"],
+    hdrs = ["version.h"],
+    local_defines = select({
+        ":embedding_enabled": [
+            "IREE_RELEASE_REVISION=\\\"$(IREE_RELEASE_REVISION)\\\"",
+            "IREE_RELEASE_VERSION=\\\"$(IREE_RELEASE_VERSION)\\\"",
+        ],
+        "//conditions:default": [],
+    }),
+)
diff --git a/compiler/src/iree/compiler/Tools/CMakeLists.txt b/compiler/src/iree/compiler/Tools/CMakeLists.txt
index 66091ec..e60b2a3 100644
--- a/compiler/src/iree/compiler/Tools/CMakeLists.txt
+++ b/compiler/src/iree/compiler/Tools/CMakeLists.txt
@@ -38,6 +38,12 @@
   list(APPEND IREE_COMPILER_TARGET_COPTS "-DIREE_HAVE_ROCM_TARGET")
 endif()
 
+set(IREE_VERSION_TARGET_COPTS "")
+if(IREE_EMBEDDED_RELEASE_INFO)
+  list(APPEND IREE_VERSION_TARGET_COPTS "-DIREE_RELEASE_REVISION=\"${IREE_RELEASE_REVISION}\"")
+  list(APPEND IREE_VERSION_TARGET_COPTS "-DIREE_RELEASE_VERSION=\"${IREE_RELEASE_VERSION}\"")
+endif()
+
 # Enable input dialects based on options.
 set(IREE_INPUT_DEPS "")
 if(IREE_INPUT_MHLO)
@@ -73,6 +79,19 @@
 
 iree_cc_library(
   NAME
+    init_iree
+  HDRS
+    "init_iree.h"
+  SRCS
+    "init_iree.cc"
+  DEPS
+    ::version
+    LLVMSupport
+  PUBLIC
+)
+
+iree_cc_library(
+  NAME
     init_iree_passes_and_dialects
   HDRS
     "init_iree_dialects.h"
@@ -209,9 +228,22 @@
   SRCS
     "iree_compile_lib.cc"
   DEPS
+    ::init_iree
     LLVMSupport
     iree::compiler::API2::Headers
     iree::compiler::API2::Internal::Embed
     iree::compiler::Pipelines
   PUBLIC
 )
+
+iree_cc_library(
+  NAME
+    version
+  HDRS
+    "version.h"
+  SRCS
+    "version.cc"
+  COPTS
+    ${IREE_VERSION_TARGET_COPTS}
+)
+
diff --git a/compiler/src/iree/compiler/Tools/init_iree.cc b/compiler/src/iree/compiler/Tools/init_iree.cc
new file mode 100644
index 0000000..91c6eeb
--- /dev/null
+++ b/compiler/src/iree/compiler/Tools/init_iree.cc
@@ -0,0 +1,43 @@
+// Copyright 2022 The IREE Authors
+//
+// Licensed under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+
+#include "iree/compiler/Tools/init_iree.h"
+
+#include "iree/compiler/Tools/version.h"
+#include "llvm/Support/CommandLine.h"
+
+static void versionPrinter(llvm::raw_ostream &os) {
+  os << "IREE (https://iree-org.github.io/):\n  ";
+  std::string version = mlir::iree_compiler::getIreeRevision();
+  if (version.empty()) {
+    version = "(unknown)";
+  }
+  os << "IREE compiler version " << version << "\n  ";
+  os << "LLVM version " << LLVM_VERSION_STRING << "\n  ";
+#if LLVM_IS_DEBUG_BUILD
+  os << "DEBUG build";
+#else
+  os << "Optimized build";
+#endif
+#ifndef NDEBUG
+  os << " with assertions";
+#endif
+#if LLVM_VERSION_PRINTER_SHOW_HOST_TARGET_INFO
+  std::string CPU = std::string(sys::getHostCPUName());
+  if (CPU == "generic") CPU = "(unknown)";
+  os << ".\n"
+     << "  Default target: " << sys::getDefaultTargetTriple() << '\n'
+     << "  Host CPU: " << CPU;
+#endif
+  os << '\n';
+}
+
+mlir::iree_compiler::InitIree::InitIree(int &argc, char **&argv)
+    : init_llvm_(argc, argv) {
+  llvm::setBugReportMsg(
+      "Please report issues to https://github.com/iree-org/iree/issues and "
+      "include the crash backtrace.\n");
+  llvm::cl::SetVersionPrinter(versionPrinter);
+}
diff --git a/compiler/src/iree/compiler/Tools/init_iree.h b/compiler/src/iree/compiler/Tools/init_iree.h
new file mode 100644
index 0000000..2ed6bde
--- /dev/null
+++ b/compiler/src/iree/compiler/Tools/init_iree.h
@@ -0,0 +1,19 @@
+#ifndef IREE_COMPILER_TOOLS_INIT_IREE_H_
+#define IREE_COMPILER_TOOLS_INIT_IREE_H_
+
+#include "llvm/Support/InitLLVM.h"
+
+namespace mlir::iree_compiler {
+
+// Helper to initialize LLVM while setting IREE specific help and versions.
+class InitIree {
+ public:
+  InitIree(int &argc, char **&argv);
+
+ private:
+  llvm::InitLLVM init_llvm_;
+};
+
+}  // namespace mlir::iree_compiler
+
+#endif  // IREE_COMPILER_TOOLS_INIT_IREE_H_
diff --git a/compiler/src/iree/compiler/Tools/iree_compile_lib.cc b/compiler/src/iree/compiler/Tools/iree_compile_lib.cc
index 220ae7a..d4211bf 100644
--- a/compiler/src/iree/compiler/Tools/iree_compile_lib.cc
+++ b/compiler/src/iree/compiler/Tools/iree_compile_lib.cc
@@ -13,6 +13,7 @@
 
 #include "iree/compiler/API2/Embed.h"
 #include "iree/compiler/Pipelines/Pipelines.h"
+#include "iree/compiler/Tools/init_iree.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/InitLLVM.h"
 #include "llvm/Support/raw_ostream.h"
@@ -49,10 +50,7 @@
 }  // namespace mlir
 
 int mlir::iree_compiler::runIreecMain(int argc, char **argv) {
-  llvm::setBugReportMsg(
-      "Please report issues to https://github.com/iree-org/iree/issues and "
-      "include the crash backtrace.\n");
-  llvm::InitLLVM y(argc, argv);
+  InitIree y(argc, argv);
   static llvm::cl::OptionCategory mainOptions("IREE Main Options");
   ireeCompilerGlobalInitialize(/*initializeCommandLine=*/true);
 
diff --git a/compiler/src/iree/compiler/Tools/version.cc b/compiler/src/iree/compiler/Tools/version.cc
new file mode 100644
index 0000000..f587a6a
--- /dev/null
+++ b/compiler/src/iree/compiler/Tools/version.cc
@@ -0,0 +1,24 @@
+// Copyright 2022 The IREE Authors
+//
+// Licensed under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+
+#include "iree/compiler/Tools/version.h"
+
+#include <string_view>
+
+std::string mlir::iree_compiler::getIreeRevision() {
+#ifdef IREE_RELEASE_VERSION
+#ifdef IREE_RELEASE_REVISION
+  if constexpr (std::string_view(IREE_RELEASE_REVISION) == "HEAD") {
+    return IREE_RELEASE_VERSION;
+  }
+  return IREE_RELEASE_VERSION " @ " IREE_RELEASE_REVISION;
+#else
+  return IREE_RELEASE_VERSION;
+#endif
+#else
+  return "";
+#endif
+}
diff --git a/compiler/src/iree/compiler/Tools/version.h b/compiler/src/iree/compiler/Tools/version.h
new file mode 100644
index 0000000..20f3385
--- /dev/null
+++ b/compiler/src/iree/compiler/Tools/version.h
@@ -0,0 +1,20 @@
+// Copyright 2022 The IREE Authors
+//
+// Licensed under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+
+#ifndef IREE_COMPILER_TOOLS_VERSION_H
+#define IREE_COMPILER_TOOLS_VERSION_H
+
+#include <string>
+
+namespace mlir::iree_compiler {
+
+// Returns the IREE compiler version. Empty if built without IREE_VERSION
+// defined.
+std::string getIreeRevision();
+
+}  // namespace mlir::iree_compiler
+
+#endif  // IREE_COMPILER_TOOLS_VERSION_H