From 69afdd2ebc5ca91b62c91bd254478a633e62a643 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Tue, 27 Jul 2021 13:45:25 -0700 Subject: [PATCH] Adding a skeleton librt to provide libc/libm/etc during embedded linking. (#6560) The code should be factored out as we start to add things like placeholder functions for querying runtime state/etc but starting simple here to get us bootstrapped. See librt/src/librt.h for some notes. Run librt/build.sh to update the .bc file and then rebuild iree-* so the new version is pulled in. --- .gitignore | 3 + iree/compiler/Dialect/HAL/Target/LLVM/BUILD | 2 + .../Dialect/HAL/Target/LLVM/CMakeLists.txt | 2 + .../Dialect/HAL/Target/LLVM/LLVMAOTTarget.cpp | 100 ++++++++++++++++-- .../LLVM/internal/EmbeddedLinkerTool.cpp | 2 +- .../Dialect/HAL/Target/LLVM/librt/BUILD | 31 ++++++ .../HAL/Target/LLVM/librt/CMakeLists.txt | 32 ++++++ .../HAL/Target/LLVM/librt/bin/librt.bc | Bin 0 -> 1348 bytes .../Dialect/HAL/Target/LLVM/librt/build.sh | 45 ++++++++ .../Dialect/HAL/Target/LLVM/librt/src/libm.c | 13 +++ .../Dialect/HAL/Target/LLVM/librt/src/libm.h | 15 +++ .../Dialect/HAL/Target/LLVM/librt/src/librt.h | 75 +++++++++++++ 12 files changed, 309 insertions(+), 11 deletions(-) create mode 100644 iree/compiler/Dialect/HAL/Target/LLVM/librt/BUILD create mode 100644 iree/compiler/Dialect/HAL/Target/LLVM/librt/CMakeLists.txt create mode 100644 iree/compiler/Dialect/HAL/Target/LLVM/librt/bin/librt.bc create mode 100644 iree/compiler/Dialect/HAL/Target/LLVM/librt/build.sh create mode 100644 iree/compiler/Dialect/HAL/Target/LLVM/librt/src/libm.c create mode 100644 iree/compiler/Dialect/HAL/Target/LLVM/librt/src/libm.h create mode 100644 iree/compiler/Dialect/HAL/Target/LLVM/librt/src/librt.h diff --git a/.gitignore b/.gitignore index 4f52c9395349..6fe9bf2ae7b5 100644 --- a/.gitignore +++ b/.gitignore @@ -58,3 +58,6 @@ local.properties # Generated documentation files mkdocs/site/ docs/website/site/ + +# Temporary files +iree/compiler/Dialect/HAL/Target/LLVM/librt/bin/librt.ll diff --git a/iree/compiler/Dialect/HAL/Target/LLVM/BUILD b/iree/compiler/Dialect/HAL/Target/LLVM/BUILD index 01c1c132f9ed..3359b98e5dba 100644 --- a/iree/compiler/Dialect/HAL/Target/LLVM/BUILD +++ b/iree/compiler/Dialect/HAL/Target/LLVM/BUILD @@ -41,12 +41,14 @@ cc_library( "//iree/compiler/Codegen/LLVMCPU", "//iree/compiler/Codegen/Utils", "//iree/compiler/Dialect/HAL/Target", + "//iree/compiler/Dialect/HAL/Target/LLVM/librt", "//iree/compiler/Utils", "//iree/schemas:dylib_executable_def_c_fbs", "@llvm-project//llvm:AArch64AsmParser", "@llvm-project//llvm:AArch64CodeGen", "@llvm-project//llvm:ARMAsmParser", "@llvm-project//llvm:ARMCodeGen", + "@llvm-project//llvm:BitReader", "@llvm-project//llvm:BitWriter", "@llvm-project//llvm:Core", "@llvm-project//llvm:RISCVAsmParser", diff --git a/iree/compiler/Dialect/HAL/Target/LLVM/CMakeLists.txt b/iree/compiler/Dialect/HAL/Target/LLVM/CMakeLists.txt index f12301bdc4b0..29c951418b6b 100644 --- a/iree/compiler/Dialect/HAL/Target/LLVM/CMakeLists.txt +++ b/iree/compiler/Dialect/HAL/Target/LLVM/CMakeLists.txt @@ -32,6 +32,7 @@ iree_cc_library( LLVMAArch64CodeGen LLVMARMAsmParser LLVMARMCodeGen + LLVMBitReader LLVMBitWriter LLVMCore LLVMRISCVAsmParser @@ -50,6 +51,7 @@ iree_cc_library( iree::compiler::Codegen::PassHeaders iree::compiler::Codegen::Utils iree::compiler::Dialect::HAL::Target + iree::compiler::Dialect::HAL::Target::LLVM::librt iree::compiler::Utils iree::schemas::dylib_executable_def_c_fbs PUBLIC diff --git a/iree/compiler/Dialect/HAL/Target/LLVM/LLVMAOTTarget.cpp b/iree/compiler/Dialect/HAL/Target/LLVM/LLVMAOTTarget.cpp index f80e47cf72d1..fdefab2b5fc5 100644 --- a/iree/compiler/Dialect/HAL/Target/LLVM/LLVMAOTTarget.cpp +++ b/iree/compiler/Dialect/HAL/Target/LLVM/LLVMAOTTarget.cpp @@ -13,9 +13,11 @@ #include "iree/compiler/Dialect/HAL/Target/LLVM/LibraryBuilder.h" #include "iree/compiler/Dialect/HAL/Target/LLVM/LinkerTool.h" #include "iree/compiler/Dialect/HAL/Target/LLVM/StaticLibraryGenerator.h" +#include "iree/compiler/Dialect/HAL/Target/LLVM/librt/librt.h" #include "iree/compiler/Dialect/HAL/Target/TargetRegistry.h" #include "iree/compiler/Utils/FlatbufferUtils.h" #include "iree/schemas/dylib_executable_def_builder.h" +#include "llvm/Bitcode/BitcodeReader.h" #include "llvm/Bitcode/BitcodeWriter.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Module.h" @@ -30,11 +32,10 @@ namespace iree_compiler { namespace IREE { namespace HAL { -namespace { +static constexpr char kQueryFunctionName[] = + "iree_hal_executable_library_query"; -constexpr char kQueryFunctionName[] = "iree_hal_executable_library_query"; - -llvm::Optional findFirstFileLoc(Location baseLoc) { +static llvm::Optional findFirstFileLoc(Location baseLoc) { if (auto loc = baseLoc.dyn_cast()) { for (auto &childLoc : loc.getLocations()) { auto childResult = findFirstFileLoc(childLoc); @@ -46,7 +47,7 @@ llvm::Optional findFirstFileLoc(Location baseLoc) { return llvm::None; } -std::string guessModuleName(mlir::ModuleOp moduleOp) { +static std::string guessModuleName(mlir::ModuleOp moduleOp) { std::string moduleName = moduleOp.getName().hasValue() ? moduleOp.getName().getValue().str() : ""; if (!moduleName.empty()) return moduleName; @@ -58,8 +59,6 @@ std::string guessModuleName(mlir::ModuleOp moduleOp) { } } -} // namespace - class LLVMAOTTargetBackend final : public TargetBackend { public: explicit LLVMAOTTargetBackend(LLVMTargetOptions options) @@ -284,8 +283,10 @@ class LLVMAOTTargetBackend final : public TargetBackend { << options_.targetTriple << "'"; } - // Emit object files. - SmallVector objectFiles; + SmallVector objectFiles; + + // Emit the base object file containing the bulk of our code. + // This must come first such that we have the proper library linking order. { // NOTE: today we just use a single object file, however if we wanted to // scale code generation and linking we'd want to generate one per @@ -306,6 +307,16 @@ class LLVMAOTTargetBackend final : public TargetBackend { objectFiles.push_back(std::move(objectFile)); } + // Optionally append additional object files that provide functionality that + // may otherwise have been runtime-dynamic (like libc/libm calls). + // For now we only do this for embedded uses. + if (options_.linkEmbedded) { + if (failed(buildLibraryObjects(variantOp.getLoc(), targetMachine.get(), + objectFiles, context))) { + return variantOp.emitError() << "failed generating library objects"; + } + } + // If we are keeping artifacts then let's also add the bitcode for easier // debugging (vs just the binary object file). if (options_.keepLinkerArtifacts) { @@ -329,7 +340,6 @@ class LLVMAOTTargetBackend final : public TargetBackend { // Copy the static object file to the specified output along with // generated header file. const std::string &libraryPath = options_.staticLibraryOutput; - const auto library_name = objectFiles[0].path; if (!outputStaticLibrary(libraryName, queryFunctionName, libraryPath, objectFiles[0].path)) { return variantOp.emitError() << "static library generation failed"; @@ -506,6 +516,76 @@ class LLVMAOTTargetBackend final : public TargetBackend { return IREE::HAL::ExecutableTargetAttr::get(context, "llvm", format); } + static void overridePlatformGlobal(llvm::Module &module, StringRef globalName, + uint32_t newValue) { + // NOTE: the global will not be defined if it is not used in the module. + auto *globalValue = module.getNamedGlobal(globalName); + if (!globalValue) return; + globalValue->setLinkage(llvm::GlobalValue::PrivateLinkage); + globalValue->setDSOLocal(true); + globalValue->setConstant(true); + globalValue->setInitializer(llvm::ConstantInt::get( + globalValue->getValueType(), APInt(32, newValue))); + } + + // Builds an object file for the librt embedded runtime library. + // This is done per link operation so that we can match the precise target + // configuration. Since we (mostly) link once per user-level compilation + // this is fine today. If in the future we invoke the compiler for thousands + // of modules we'd want to (carefully) cache this. + LogicalResult buildLibraryObjects(Location loc, + llvm::TargetMachine *targetMachine, + SmallVector &objectFiles, + llvm::LLVMContext &context) { + assert(!objectFiles.empty() && "libraries must come after the base object"); + + // Load the generic bitcode file contents. + llvm::MemoryBufferRef bitcodeBufferRef( + llvm::StringRef(iree_compiler_librt_create()->data, + iree_compiler_librt_create()->size), + "librt.bc"); + auto bitcodeModuleValue = llvm::parseBitcodeFile(bitcodeBufferRef, context); + if (!bitcodeModuleValue) { + return mlir::emitError(loc) + << "failed to parse librt bitcode: " + << llvm::toString(bitcodeModuleValue.takeError()); + } + auto bitcodeModule = std::move(bitcodeModuleValue.get()); + bitcodeModule->setDataLayout(targetMachine->createDataLayout()); + bitcodeModule->setTargetTriple(targetMachine->getTargetTriple().str()); + + // Inject target-specific flags. + // TODO(benvanik): move this entire function to another file that can do + // more complex logic cleanly. This is just an example. + overridePlatformGlobal(*bitcodeModule, "librt_platform_example_flag", 0u); + + // Run the LLVM passes to optimize it for the current target. + if (failed(runLLVMIRPasses(options_, targetMachine, bitcodeModule.get()))) { + return mlir::emitError(loc) + << "failed to run librt LLVM-IR opt passes targeting '" + << options_.targetTriple << "'"; + } + + // Emit an object file we can pass to the linker. + std::string objectData; + if (failed(runEmitObjFilePasses(targetMachine, bitcodeModule.get(), + &objectData))) { + return mlir::emitError(loc) + << "failed to compile librt LLVM-IR module to an object file"; + } + + // Write the object file to disk with a similar name to the base file. + auto objectFile = + Artifact::createVariant(objectFiles.front().path, ".librt.o"); + auto &os = objectFile.outputFile->os(); + os << objectData; + os.flush(); + os.close(); + objectFiles.push_back(std::move(objectFile)); + + return success(); + } + LLVMTargetOptions options_; }; diff --git a/iree/compiler/Dialect/HAL/Target/LLVM/internal/EmbeddedLinkerTool.cpp b/iree/compiler/Dialect/HAL/Target/LLVM/internal/EmbeddedLinkerTool.cpp index f2847c23bf1d..cda219ea5e08 100644 --- a/iree/compiler/Dialect/HAL/Target/LLVM/internal/EmbeddedLinkerTool.cpp +++ b/iree/compiler/Dialect/HAL/Target/LLVM/internal/EmbeddedLinkerTool.cpp @@ -80,7 +80,7 @@ class EmbeddedLinkerTool : public LinkerTool { // Create the shared object name; if we only have a single input object we // can just reuse that. - if (objectFiles.size() == 1) { + if (!objectFiles.empty()) { artifacts.libraryFile = Artifact::createVariant(objectFiles.front().path, "so"); } else { diff --git a/iree/compiler/Dialect/HAL/Target/LLVM/librt/BUILD b/iree/compiler/Dialect/HAL/Target/LLVM/librt/BUILD new file mode 100644 index 000000000000..f9f6feb86ee8 --- /dev/null +++ b/iree/compiler/Dialect/HAL/Target/LLVM/librt/BUILD @@ -0,0 +1,31 @@ +# 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 + +load("//build_tools/embed_data:build_defs.bzl", "c_embed_data") +load("//iree:build_defs.oss.bzl", "iree_cmake_extra_content") + +package( + default_visibility = ["//visibility:public"], + features = ["layering_check"], + licenses = ["notice"], # Apache 2.0 +) + +iree_cmake_extra_content( + content = """ +if(NOT "${IREE_TARGET_BACKEND_DYLIB-LLVM-AOT}" AND NOT "${IREE_TARGET_BACKEND_WASM-LLVM-AOT}") + return() +endif() +""", +) + +c_embed_data( + name = "librt", + srcs = ["bin/librt.bc"], + c_file_output = "librt.c", + flatten = True, + h_file_output = "librt.h", + identifier = "iree_compiler_librt", +) diff --git a/iree/compiler/Dialect/HAL/Target/LLVM/librt/CMakeLists.txt b/iree/compiler/Dialect/HAL/Target/LLVM/librt/CMakeLists.txt new file mode 100644 index 000000000000..c6dabe0cded8 --- /dev/null +++ b/iree/compiler/Dialect/HAL/Target/LLVM/librt/CMakeLists.txt @@ -0,0 +1,32 @@ +################################################################################ +# Autogenerated by build_tools/bazel_to_cmake/bazel_to_cmake.py from # +# iree/compiler/Dialect/HAL/Target/LLVM/librt/BUILD # +# # +# Use iree_cmake_extra_content from iree/build_defs.oss.bzl to add arbitrary # +# CMake-only content. # +# # +# To disable autogeneration for this file entirely, delete this header. # +################################################################################ + +if(NOT "${IREE_TARGET_BACKEND_DYLIB-LLVM-AOT}" AND NOT "${IREE_TARGET_BACKEND_WASM-LLVM-AOT}") + return() +endif() + +iree_add_all_subdirs() + +iree_c_embed_data( + NAME + librt + SRCS + "bin/librt.bc" + C_FILE_OUTPUT + "librt.c" + H_FILE_OUTPUT + "librt.h" + IDENTIFIER + "iree_compiler_librt" + FLATTEN + PUBLIC +) + +### BAZEL_TO_CMAKE_PRESERVES_ALL_CONTENT_BELOW_THIS_LINE ### diff --git a/iree/compiler/Dialect/HAL/Target/LLVM/librt/bin/librt.bc b/iree/compiler/Dialect/HAL/Target/LLVM/librt/bin/librt.bc new file mode 100644 index 0000000000000000000000000000000000000000..a484f31e2ae70ba1d559a6ddc1d8c6211baed60d GIT binary patch literal 1348 zcmXX`Z*0>>6u;DIY?^R(+6oftSat(b1ZcSF{v=I;nz%sNGL{NHbQ%*$|3vLpN}5Lf z$2O(0JBKZr(yp2!tsk1fmuX+ZR!wL_Q&Sg~u?PV|Q`xGjQA1%&MU=|IWXuZIAg>$j0daIEV(?Dh^bk`3}_a z3G7_iFGNHs;~7W zl3GdfQEW4q1YpiUq|E?}>tpsRKRN>14FF(BHzd~nLk*9i@lj-}V5o}&u#59Sa&`9D zu^&DV_QnVR2*9ExfF#k{DYmv}0Eq3UfCibYOj>8u`%=kmFC4k57QU>tsK3`E`$gpM zGo+h|7`;@aL-i_GLa<3n(i6kSM)9Hapl$<@4=DIJ2Ag#rW-({Fo}oj0_0~4Ap@6ya zf-8x+3Zuzr7(YwkV_rEN#>d0h@TeSSWn)1PH&d|4lLI`tUWR2qY^Ih>s~o+|nHGag zh(G7JEIMuo_Ib>CS#(O6qfo9N4&Y~d@mG802$C^5oRY%II<%gvdTyG_dEZjsW zSc_>T$1J*;TO7SI!K|#&rK0Ii6%#VF+p z7NqZUrq!J3LlsjAm@}1wniG?vt)Muvf(s?&>7uhFI1*^8B(KyUr1A)ghrq`zcqBb> za-D*k3-GQVKH|-}TW+RQ+__vdt)c+DMn_h3&5I3^VoM74g5tcCv*#6r(OK}$4-zbK|2Wy%#OWx(lyDa&S9}ZA(orh@pXif9S8Z7zY6J99(#+f!UbXm0( zdGPS7Fr5IOG0QtsBZ`d!59m`PQxM*S?{q zF0JE>hCPU}0DOgHg}>UGhz0QhAMXgK1s5u7Rimt?_q@l!oGd%36I-dIV*K7 zQ*?vI?0!Wz8SgiIUabPndZ14(`qZuJ^L(9(%2{*`l-L9mjpWxYWL0_!YsGZC0<#pM z=Z_HqF@~_?$k*E+aUI|3+Oqw|j{|qChTJzjws_AkDYdo|6l#O)v-iUasYVIRRGzx6 f_6`D3IbVy-=tHN2p(g%C^f`y3-F*WGpYQn}B!I3+ literal 0 HcmV?d00001 diff --git a/iree/compiler/Dialect/HAL/Target/LLVM/librt/build.sh b/iree/compiler/Dialect/HAL/Target/LLVM/librt/build.sh new file mode 100644 index 000000000000..c671e4d8df97 --- /dev/null +++ b/iree/compiler/Dialect/HAL/Target/LLVM/librt/build.sh @@ -0,0 +1,45 @@ +# 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 + +set -e + +SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" +OUT="${SCRIPT_DIR}/bin" +SRC="${SCRIPT_DIR}/src" +LL_FILE="${OUT}/librt.ll" +BC_FILE="${OUT}/librt.bc" + +# Generate an LLVM IR assembly listing so we can easily read the file. +# This is not checked in or used by the compiler. +clang \ + -target wasm32 \ + -std=c17 \ + -O2 \ + -Xclang -disable-llvm-passes \ + -fno-ident \ + -fvisibility=hidden \ + -nostdinc \ + -g0 \ + -S \ + -emit-llvm \ + -fno-verbose-asm \ + -fdiscard-value-names \ + -o "${LL_FILE}" \ + -c \ + "${SRC}/libm.c" + +# Clang adds a bunch of bad attributes and host-specific information that we +# don't want (so we get at least somewhat deterministic builds). +sed -i 's/^;.*$//' ${LL_FILE} +sed -i 's/^source_filename.*$//' ${LL_FILE} +sed -i 's/^target datalayout.*$//' ${LL_FILE} +sed -i 's/^target triple.*$//' ${LL_FILE} +sed -i 's/^\(attributes #[0-9]* = {\).*$/\1 inlinehint }/' ${LL_FILE} + +# Generate a binary bitcode file embedded into the compiler binary. +# NOTE: we do this from stdin so that the filename on the user's system is not +# embedded in the bitcode file (making it non-deterministic). +cat ${LL_FILE} | llvm-as -o=${BC_FILE} diff --git a/iree/compiler/Dialect/HAL/Target/LLVM/librt/src/libm.c b/iree/compiler/Dialect/HAL/Target/LLVM/librt/src/libm.c new file mode 100644 index 000000000000..bdbe0aeaf104 --- /dev/null +++ b/iree/compiler/Dialect/HAL/Target/LLVM/librt/src/libm.c @@ -0,0 +1,13 @@ +// 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 "libm.h" + +// https://en.cppreference.com/w/c/numeric/math/fma +LIBRT_EXPORT float fmaf(float x, float y, float z) { + // TODO(*): a real implementation :) + return (x * y) + z; +} diff --git a/iree/compiler/Dialect/HAL/Target/LLVM/librt/src/libm.h b/iree/compiler/Dialect/HAL/Target/LLVM/librt/src/libm.h new file mode 100644 index 000000000000..10dfe762a375 --- /dev/null +++ b/iree/compiler/Dialect/HAL/Target/LLVM/librt/src/libm.h @@ -0,0 +1,15 @@ +// 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 + +#ifndef IREE_COMPILER_DIALECT_HAL_TARGET_LLVM_LIBRT_SRC_LIBM_H_ +#define IREE_COMPILER_DIALECT_HAL_TARGET_LLVM_LIBRT_SRC_LIBM_H_ + +#include "librt.h" + +// https://en.cppreference.com/w/c/numeric/math/fma +LIBRT_EXPORT float fmaf(float x, float y, float z); + +#endif // IREE_COMPILER_DIALECT_HAL_TARGET_LLVM_LIBRT_SRC_LIBM_H_ diff --git a/iree/compiler/Dialect/HAL/Target/LLVM/librt/src/librt.h b/iree/compiler/Dialect/HAL/Target/LLVM/librt/src/librt.h new file mode 100644 index 000000000000..0af8b21cc5f5 --- /dev/null +++ b/iree/compiler/Dialect/HAL/Target/LLVM/librt/src/librt.h @@ -0,0 +1,75 @@ +// 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 + +//===----------------------------------------------------------------------===// +// A simplified libc/libm-alike that is designed to compile to portable LLVM IR. +//===----------------------------------------------------------------------===// +// This library is focused on supporting the subset of LLVM's RuntimeLibcalls +// that we need in our embedded executable binaries. This means that things like +// printf, malloc, etc are excluded. +// +// See the full list of possible functions here: +// third_party/llvm-project/llvm/include/llvm/IR/RuntimeLibcalls.def +// +// Code here must not use any system headers - as almost all pull in bits/ and +// various other target-dependent definitions that make the resulting IR +// non-portable. This means there is no size_t, etc. Any definitions that may +// come from an std* file must be redefined here with care. +// +// Code must also not use any mutable global or thread-local state ala +// errno/rounding modes/etc. Each of the functions in the library will be called +// concurrently from multiple threads and from multiple source modules. There +// must be no mutable static values anywhere. +// +// Avoid #ifdef entirely: they indicate a leakage of host build configuration +// into what is supposed to be a portable module. Anything that requires +// target-specific conditional logic must be implemented via an extern that +// can be substituted by the IREE compiler when producing the final +// target-specific module. + +//===----------------------------------------------------------------------===// +// Attributes and metadata +//===----------------------------------------------------------------------===// + +// Tagged on functions that are part of the public API. +#define LIBRT_EXPORT __attribute__((visibility("hidden"))) + +//===----------------------------------------------------------------------===// +// stdint.h +//===----------------------------------------------------------------------===// +// https://pubs.opengroup.org/onlinepubs/009604599/basedefs/stdint.h.html +// NOTE: no size_t/ptrdiff_t/etc (as they are target dependent). + +typedef signed char int8_t; +typedef short int16_t; +typedef int int32_t; +typedef long long int64_t; +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef unsigned int uint32_t; +typedef unsigned long long uint64_t; + +#define INT8_MIN (-127i8 - 1) +#define INT16_MIN (-32767i16 - 1) +#define INT32_MIN (-2147483647i32 - 1) +#define INT64_MIN (-9223372036854775807i64 - 1) +#define INT8_MAX 127i8 +#define INT16_MAX 32767i16 +#define INT32_MAX 2147483647i32 +#define INT64_MAX 9223372036854775807i64 +#define UINT8_MAX 0xffui8 +#define UINT16_MAX 0xffffui16 +#define UINT32_MAX 0xffffffffui32 +#define UINT64_MAX 0xffffffffffffffffui64 + +//===----------------------------------------------------------------------===// +// Target-specific queries +//===----------------------------------------------------------------------===// +// These are substituted with values from the compiler and must not be specified +// here in C before we generate the IR. + +// Do not use: here as an example. Remove once we have any other flag. +extern int librt_platform_example_flag;