Skip to content

Commit

Permalink
Add a busybox style iree-lld tool. (iree-org#7186)
Browse files Browse the repository at this point in the history
* I'm not sure this is a good idea. But also not sure it is bad.
* The intent here is that for distribution (i.e. as part of the Python API), we can have a standalone LLD tool which links against the common compiler .so/.dll, saving quite a bit of binary size (i.e. a standalone lld is on the same order of magnitude of ~everything else whereas bundling adds 20-30% on disk and potentially saves shared memory, etc).
* I don't think this is out of bounds of the upstream policy of not supporting LLD-as-a-library: we still only use it as a standalone process, just allow it to be linked with everything.
* Doesn't actually use the tool yet: would need some plumbing to make sure the various things select it and consistently pass -flavor vs relying on name-based sniffing.
  • Loading branch information
stellaraccident authored Oct 21, 2021
1 parent 1f33d06 commit 76138f4
Show file tree
Hide file tree
Showing 6 changed files with 156 additions and 15 deletions.
8 changes: 6 additions & 2 deletions llvm-external-projects/iree-compiler-api/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ if(IREE_COMPILER_API_SUB_PROJECT)
message(STATUS "Building iree-compiler-api as part of IREE")
set(LLVM_MAIN_SRC_DIR "${IREE_SOURCE_DIR}/third_party/llvm-project/llvm")
set(LLVM_MAIN_BINARY_DIR "${IREE_BINARY_DIR}/third_party/llvm-project")
set(MLIR_MAIN_BINARY_DIR "${LLVM_MAIN_BINARY_DIR}/tools/mlir")
else()
# Standalone build.
message(STATUS "Building iree-compiler-api standalone")
Expand All @@ -42,7 +41,6 @@ else()
set(IREE_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/iree")
set(LLVM_MAIN_SRC_DIR "${IREE_COMPILER_API_SOURCE_DIR}/../../third_party/llvm-project/llvm")
set(LLVM_MAIN_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/llvm")
set(MLIR_MAIN_BINARY_DIR "${LLVM_MAIN_BINARY_DIR}/tools/mlir")
set(LLVM_EXTERNAL_MLIR_HLO_SOURCE_DIR "${IREE_COMPILER_API_SOURCE_DIR}/../../third_party/mlir-hlo")
# Resources generated on windows must have valid version numbers.
# See set_windows_version_resource_properties.
Expand All @@ -62,7 +60,11 @@ message(STATUS "iree-compiler-api Directories:
LLVM_MAIN_BINARY_DIR = ${LLVM_MAIN_BINARY_DIR}
")

# LLVM dependent project directories.
set(LLD_MAIN_SRC_DIR ${LLVM_MAIN_SRC_DIR}/../lld)
set(LLD_MAIN_BINARY_DIR ${LLVM_MAIN_BINARY_DIR}/tools/lld)
set(MLIR_MAIN_SRC_DIR ${LLVM_MAIN_SRC_DIR}/../mlir)
set(MLIR_MAIN_BINARY_DIR "${LLVM_MAIN_BINARY_DIR}/tools/mlir")

# Configuration includes.
include(${IREE_SOURCE_DIR}/build_tools/cmake/iree_third_party_cmake_options.cmake)
Expand All @@ -88,6 +90,8 @@ endmacro()

add_system_include_hack(${LLVM_MAIN_SRC_DIR}/include)
add_system_include_hack(${LLVM_MAIN_BINARY_DIR}/include)
add_system_include_hack(${LLD_MAIN_SRC_DIR}/include)
add_system_include_hack(${LLD_MAIN_BINARY_DIR}/include)
add_system_include_hack(${MLIR_MAIN_SRC_DIR}/include)
add_system_include_hack(${MLIR_MAIN_BINARY_DIR}/include)
add_system_include_hack(${IREE_SOURCE_DIR})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ extern "C" {
/// binaries that link against a common shared library.
MLIR_CAPI_EXPORTED int ireeCompilerRunMain(int argc, char **argv);

/// Runs LLD in "generic" mode (i.e. as `lld`, requiring a -flavor command line
/// option). This does *not* mean that we support invoking LLD as a library,
/// but we do support creating busybox style tools that invoke it standalone
/// by linking against the CAPI.
MLIR_CAPI_EXPORTED int ireeCompilerRunLldMain(int argc, char **argv);

#ifdef __cplusplus
}
#endif
Expand Down
10 changes: 10 additions & 0 deletions llvm-external-projects/iree-compiler-api/lib/CAPI/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
add_mlir_public_c_api_library(IREECompilerAPICompilerCAPI
Compiler.cpp
Lld.cpp
Tools.cpp
# TODO: If installing, complains about IREEVM not being in any export set.
DISABLE_INSTALL
Expand All @@ -16,6 +17,15 @@ add_mlir_public_c_api_library(IREECompilerAPICompilerCAPI

# Tools.
iree::tools::iree_translate_lib

# LLD.
lldCommon
lldCOFF
lldDriver
lldELF
lldMachO
lldMinGW
lldWasm
)

# TODO: Fix upstream so there is a way to know what the actual compile target
Expand Down
93 changes: 93 additions & 0 deletions llvm-external-projects/iree-compiler-api/lib/CAPI/Lld.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
// Copyright 2021 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

// See llvm-project/lld/tools/lld/lld.cpp. Much of that is scaffolding for
// supporting symlink based lld which auto-detects the flavor. Instead, we
// duplicate the flavor parsing and invoke the backend directly similar to
// what the lldMain() does.

#include <cstdlib>
#include <vector>

#include "iree-compiler-c/Tools.h"
#include "lld/Common/Driver.h"
#include "lld/Common/ErrorHandler.h"
#include "lld/Common/Memory.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/ADT/Triple.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/CrashRecoveryContext.h"
#include "llvm/Support/Host.h"
#include "llvm/Support/InitLLVM.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/PluginLoader.h"
#include "llvm/Support/Process.h"

using namespace lld;
using namespace llvm;
using namespace llvm::sys;

enum Flavor {
Invalid,
Gnu, // -flavor gnu
WinLink, // -flavor link
Darwin, // -flavor darwin
Wasm, // -flavor wasm
};

[[noreturn]] static void die(const Twine &s) {
llvm::errs() << s << "\n";
exit(1);
}

static Flavor getFlavor(StringRef s) {
return StringSwitch<Flavor>(s)
.CasesLower("ld", "ld.lld", "gnu", Gnu)
.CasesLower("wasm", "ld-wasm", Wasm)
.CaseLower("link", WinLink)
.CasesLower("ld64", "ld64.lld", "darwin", "darwinnew",
"ld64.lld.darwinnew", Darwin)
.Default(Invalid);
}

static Flavor parseFlavor(std::vector<const char *> &v) {
// Parse -flavor option.
if (v.size() > 1 && v[1] == StringRef("-flavor")) {
if (v.size() <= 2) die("missing arg value for '-flavor'");
Flavor f = getFlavor(v[2]);
if (f == Invalid) die("Unknown flavor: " + StringRef(v[2]));
v.erase(v.begin() + 1, v.begin() + 3);
return f;
}
die("Expected -flavor <gnu|link|darwin|wasm>");
}

int ireeCompilerRunLldMain(int argc, char **argv) {
InitLLVM x(argc, argv);
sys::Process::UseANSIEscapeCodes(true);
bool exitEarly = true;
llvm::raw_ostream &stdoutOS = llvm::outs();
llvm::raw_ostream &stderrOS = llvm::errs();

std::vector<const char *> args(argv, argv + argc);
switch (parseFlavor(args)) {
case Gnu:
return !elf::link(args, exitEarly, stdoutOS, stderrOS);
case WinLink:
return !coff::link(args, exitEarly, stdoutOS, stderrOS);
case Darwin:
return !macho::link(args, exitEarly, stdoutOS, stderrOS);
case Wasm:
return !lld::wasm::link(args, exitEarly, stdoutOS, stderrOS);
default:
die("lld is a generic driver.\n"
"Invoke ld.lld (Unix), ld64.lld (macOS), lld-link (Windows), wasm-ld"
" (WebAssembly) instead");
}
}
45 changes: 32 additions & 13 deletions llvm-external-projects/iree-compiler-api/python/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -100,21 +100,40 @@ add_mlir_python_modules(IREECompilerPythonModules
# Tools linked against the shared CAPI library
################################################################################

# Build the ireec tool into _mlir_libs.
add_executable(
function(add_iree_compiler_busybox_tool target)
cmake_parse_arguments(ARG
""
"OUTPUT_NAME"
"SRCS"
${ARGN})

add_executable(
${target}
${ARG_SRCS}
)
target_link_libraries(${target} IREECompilerAggregateCAPI)
set_target_properties(${target}
PROPERTIES
OUTPUT_NAME "${ARG_OUTPUT_NAME}"
RUNTIME_OUTPUT_DIRECTORY "${IREE_COMPILER_API_BINARY_DIR}/python_package/iree/compiler/_mlir_libs"
)
mlir_python_setup_extension_rpath(${target})
add_dependencies(IREECompilerPythonModules ${target})
install(TARGETS ${target}
DESTINATION "python_package/iree/compiler/_mlir_libs"
)
endfunction()

add_iree_compiler_busybox_tool(
IREECompilerIREECTool
OUTPUT_NAME ireec
SRCS
IREECTool.c
)
target_link_libraries(IREECompilerIREECTool IREECompilerAggregateCAPI)
set_target_properties(IREECompilerIREECTool
PROPERTIES
OUTPUT_NAME "ireec"
RUNTIME_OUTPUT_DIRECTORY "${IREE_COMPILER_API_BINARY_DIR}/python_package/iree/compiler/_mlir_libs"
)
mlir_python_setup_extension_rpath(IREECompilerIREECTool)
add_dependencies(IREECompilerPythonModules IREECompilerIREECTool)

# Install tools.
install(TARGETS IREECompilerIREECTool
DESTINATION "python_package/iree/compiler/_mlir_libs"
add_iree_compiler_busybox_tool(
IREECompilerLldTool
OUTPUT_NAME iree-lld
SRCS
LldTool.c
)
9 changes: 9 additions & 0 deletions llvm-external-projects/iree-compiler-api/python/LldTool.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Copyright 2021 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-c/Tools.h"

int main(int argc, char **argv) { return ireeCompilerRunLldMain(argc, argv); }

0 comments on commit 76138f4

Please sign in to comment.