[mpact][tools] set up the mpact-opt tool (#10)

* [mpact][tools] set up the mpact-opt tool

* fix comments.
diff --git a/.gitignore b/.gitignore
index b6e8e5b..72af6fc 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,3 @@
-mpact_venv/
+*_venv/
 __pycache__
-/build/
+/build*/
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 933e6b4..0063ba9 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -15,6 +15,35 @@
 
 set(MPACT_PYTHON_PACKAGES_DIR "${MPACT_BINARY_DIR}/python_packages")
 
+#-------------------------------------------------------------------------------
+# Configure out-of-tree vs in-tree build
+#-------------------------------------------------------------------------------
+
+if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
+  message(STATUS "MPACT out-of-tree build.")
+  message(FATAL_ERROR "TODO")
+else()
+  message(STATUS "MPACT in-tree build.")
+  # In-tree build with LLVM_EXTERNAL_PROJECTS=mpact
+
+  option(MLIR_ENABLE_BINDINGS_PYTHON "Enables MLIR Python Bindings" OFF)
+
+  # TODO: Fix this upstream so that global include directories are not needed.
+  set(MLIR_MAIN_SRC_DIR ${LLVM_MAIN_SRC_DIR}/../mlir)
+  set(MLIR_INCLUDE_DIR ${LLVM_MAIN_SRC_DIR}/../mlir/include)
+  set(MLIR_GENERATED_INCLUDE_DIR ${LLVM_BINARY_DIR}/tools/mlir/include)
+  set(MLIR_INCLUDE_DIRS "${MLIR_INCLUDE_DIR};${MLIR_GENERATED_INCLUDE_DIR}")
+endif()
+
+include_directories(${LLVM_INCLUDE_DIRS})
+include_directories(${MLIR_INCLUDE_DIRS})
+include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
+include_directories(${CMAKE_CURRENT_BINARY_DIR}/include)
+
+add_subdirectory(include)
+add_subdirectory(lib)
+add_subdirectory(tools)
+
 add_subdirectory(benchmark)
 add_subdirectory(python)
 add_subdirectory(test)
diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/include/CMakeLists.txt
diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/lib/CMakeLists.txt
diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt
new file mode 100644
index 0000000..b7c3ca5
--- /dev/null
+++ b/tools/CMakeLists.txt
@@ -0,0 +1 @@
+add_subdirectory(mpact-opt)
diff --git a/tools/mpact-opt/CMakeLists.txt b/tools/mpact-opt/CMakeLists.txt
new file mode 100644
index 0000000..ea60836
--- /dev/null
+++ b/tools/mpact-opt/CMakeLists.txt
@@ -0,0 +1,15 @@
+add_llvm_executable(mpact-opt mpact_opt.cpp)
+
+set(dependency_libraries)
+if(TORCH_MLIR_ENABLE_STABLEHLO)
+  list(APPEND dependency_libraries StablehloRegister)
+endif()
+
+target_link_libraries(mpact-opt PRIVATE
+  MLIROptLib
+  MLIRTransforms
+  TorchMLIRInitAll
+  TorchMLIRTorchDialect
+  TorchMLIRTorchPasses
+  ${dependency_libraries}
+)
diff --git a/tools/mpact-opt/mpact_opt.cpp b/tools/mpact-opt/mpact_opt.cpp
new file mode 100644
index 0000000..a7e5736
--- /dev/null
+++ b/tools/mpact-opt/mpact_opt.cpp
@@ -0,0 +1,46 @@
+//===- mpact-opt.cpp - MLIR Optimizer Driver -------------------------===//
+//
+// Part of the MPACT Project, 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
+// Also available under a BSD-style license. See LICENSE.
+//
+//===----------------------------------------------------------------------===//
+
+#include "mlir/Dialect/SCF/IR/SCF.h"
+#include "mlir/Dialect/Tensor/IR/Tensor.h"
+#include "mlir/Tools/mlir-opt/MlirOptMain.h"
+#include "mlir/Transforms/Passes.h"
+#include "torch-mlir/InitAll.h"
+
+#ifdef TORCH_MLIR_ENABLE_STABLEHLO
+#include "stablehlo/dialect/Register.h"
+#endif
+
+using namespace mlir;
+
+int main(int argc, char **argv) {
+  mlir::torch::registerAllPasses();
+
+  // Core Transforms
+  registerCanonicalizerPass();
+  registerCSEPass();
+  registerInlinerPass();
+  registerLocationSnapshotPass();
+  registerLoopInvariantCodeMotionPass();
+  registerPrintOpStatsPass();
+  registerViewOpGraphPass();
+  registerStripDebugInfoPass();
+  registerSymbolDCEPass();
+
+  DialectRegistry registry;
+  mlir::torch::registerAllDialects(registry);
+  mlir::torch::registerOptionalInputDialects(registry);
+
+#ifdef TORCH_MLIR_ENABLE_STABLEHLO
+  mlir::stablehlo::registerAllDialects(registry);
+#endif
+  return mlir::asMainReturnCode(mlir::MlirOptMain(
+      argc, argv, "MLIR modular optimizer driver\n", registry));
+}