feat: add LLVM C API bindings (#1497)
Co-authored-by: Sebastian Ullrich <sebasti@nullri.ch> Co-authored-by: Gabriel Ebner <gebner@gebner.org>
This commit is contained in:
parent
1b73fa3fa1
commit
4d47c8abc6
11 changed files with 1718 additions and 18 deletions
|
|
@ -1,12 +1,12 @@
|
|||
{ debug ? false, stage0debug ? false, extraCMakeFlags ? [],
|
||||
stdenv, lib, cmake, gmp, gnumake, bash, buildLeanPackage, writeShellScriptBin, runCommand, symlinkJoin, lndir, perl, gnused, darwin,
|
||||
stdenv, lib, cmake, gmp, gnumake, bash, buildLeanPackage, writeShellScriptBin, runCommand, symlinkJoin, lndir, perl, gnused, darwin, llvmPackages,
|
||||
... } @ args:
|
||||
with builtins;
|
||||
rec {
|
||||
inherit stdenv;
|
||||
buildCMake = args: stdenv.mkDerivation ({
|
||||
nativeBuildInputs = [ cmake ];
|
||||
buildInputs = [ gmp ];
|
||||
buildInputs = [ gmp llvmPackages.llvm ];
|
||||
# https://github.com/NixOS/nixpkgs/issues/60919
|
||||
hardeningDisable = [ "all" ];
|
||||
dontStrip = (args.debug or debug);
|
||||
|
|
@ -16,7 +16,7 @@ rec {
|
|||
'';
|
||||
} // args // {
|
||||
src = args.realSrc or (lib.sourceByRegex args.src [ "[a-z].*" "CMakeLists\.txt" ]);
|
||||
cmakeFlags = (args.cmakeFlags or [ "-DSTAGE=1" "-DPREV_STAGE=./faux-prev-stage" "-DUSE_GITHASH=OFF" ]) ++ (args.extraCMakeFlags or extraCMakeFlags) ++ lib.optional (args.debug or debug) [ "-DCMAKE_BUILD_TYPE=Debug" ];
|
||||
cmakeFlags = (args.cmakeFlags or [ "-DSTAGE=1" "-DLLVM=ON" "-DPREV_STAGE=./faux-prev-stage" "-DUSE_GITHASH=OFF" ]) ++ (args.extraCMakeFlags or extraCMakeFlags) ++ lib.optional (args.debug or debug) [ "-DCMAKE_BUILD_TYPE=Debug" ];
|
||||
preConfigure = args.preConfigure or "" + ''
|
||||
# ignore absence of submodule
|
||||
sed -i 's!lake/Lake.lean!!' CMakeLists.txt
|
||||
|
|
@ -114,6 +114,7 @@ rec {
|
|||
LEAN_CC=${stdenv.cc}/bin/cc ${lean-bin-tools-unwrapped}/bin/leanc -shared ${lib.optionalString stdenv.isLinux "-Bsymbolic"} \
|
||||
${if stdenv.isDarwin then "-Wl,-force_load,${Init.staticLib}/libInit.a -Wl,-force_load,${Lean.staticLib}/libLean.a -Wl,-force_load,${leancpp}/lib/lean/libleancpp.a ${leancpp}/lib/libleanrt_initial-exec.a -lc++"
|
||||
else "-Wl,--whole-archive -lInit -lLean -lleancpp ${leancpp}/lib/libleanrt_initial-exec.a -Wl,--no-whole-archive -lstdc++"} -lm ${stdlibLinkFlags} \
|
||||
$(${llvmPackages.libllvm.dev}/bin/llvm-config --ldflags --libs) \
|
||||
-o $out/$libName
|
||||
'';
|
||||
mods = Init.mods // Lean.mods;
|
||||
|
|
@ -143,6 +144,7 @@ rec {
|
|||
preConfigure = ''
|
||||
cd src
|
||||
'';
|
||||
extraCMakeFlags = [ "-DLLVM=OFF" ];
|
||||
postConfigure = ''
|
||||
patchShebangs ../../tests
|
||||
rm -r bin lib include share
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ let
|
|||
stdenv' = if stdenv.isLinux then useGoldLinker stdenv else stdenv;
|
||||
lean = callPackage (import ./bootstrap.nix) (args // {
|
||||
stdenv = overrideCC stdenv' cc;
|
||||
inherit buildLeanPackage;
|
||||
inherit buildLeanPackage llvmPackages;
|
||||
});
|
||||
makeOverridableLeanPackage = f:
|
||||
let newF = origArgs: f origArgs // {
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ $CP -r llvm/include/*-*-* llvm-host/include/
|
|||
$CP $GLIBC/lib/libc_nonshared.a stage1/lib/glibc
|
||||
for f in $GLIBC/lib/lib{c,dl,m,rt,pthread}-*; do b=$(basename $f); cp $f stage1/lib/glibc/${b%-*}.so; done
|
||||
OPTIONS=()
|
||||
echo -n " -DLLVM=ON -DLLVM_CONFIG=$PWD/llvm-host/bin/llvm-config" # manually point to `llvm-config` location
|
||||
echo -n " -DLEAN_STANDALONE=ON"
|
||||
echo -n " -DCMAKE_CXX_COMPILER=$PWD/llvm-host/bin/clang++ -DLEAN_CXX_STDLIB='-Wl,-Bstatic -lc++ -lc++abi -Wl,-Bdynamic'"
|
||||
echo -n " -DLEAN_EXTRA_CXX_FLAGS='--sysroot $PWD/llvm -idirafter $GLIBC_DEV/include ${EXTRA_FLAGS:-}'"
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ $CP llvm/lib/clang/*/include/{std*,__std*,limits}.h stage1/include/clang
|
|||
cp $SDK/usr/lib/libSystem.tbd stage1/lib/libc
|
||||
# use for linking, use system libs for running
|
||||
gcp llvm/lib/lib{c++,c++abi,unwind}.dylib stage1/lib/libc
|
||||
echo -n " -DLLVM=ON -DLLVM_CONFIG=$PWD/llvm-host/bin/llvm-config" # manually point to `llvm-config` location
|
||||
echo -n " -DLEAN_STANDALONE=ON"
|
||||
# do not change C++ compiler; libc++ etc. being system libraries means there's no danger of conflicts,
|
||||
# and the custom clang++ outputs a myriad of warnings when consuming the SDK
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ cp /clang64/lib/{crtbegin,crtend,crt2,dllcrt2}.o stage1/lib/
|
|||
(cd llvm; cp --parents lib/clang/*/lib/*/libclang_rt.builtins* ../stage1)
|
||||
# further dependencies
|
||||
cp /clang64/lib/lib{m,bcrypt,mingw32,moldname,mingwex,msvcrt,pthread,advapi32,shell32,user32,kernel32,ucrtbase}.* /clang64/lib/libgmp.a llvm/lib/lib{c++,c++abi,unwind}.a stage1/lib/
|
||||
echo -n " -DLLVM=ON -DLLVM_CONFIG=$PWD/llvm/bin/llvm-config" # manually point to `llvm-config` location
|
||||
echo -n " -DLEAN_STANDALONE=ON"
|
||||
echo -n " -DCMAKE_C_COMPILER=$PWD/stage1/bin/clang.exe -DCMAKE_C_COMPILER_WORKS=1 -DCMAKE_CXX_COMPILER=$PWD/llvm/bin/clang++.exe -DCMAKE_CXX_COMPILER_WORKS=1 -DLEAN_CXX_STDLIB='-lc++ -lc++abi'"
|
||||
echo -n " -DSTAGE0_CMAKE_C_COMPILER=clang -DSTAGE0_CMAKE_CXX_COMPILER=clang++"
|
||||
|
|
|
|||
|
|
@ -157,19 +157,6 @@ if(AUTO_THREAD_FINALIZATION AND NOT MSVC)
|
|||
string(APPEND LEAN_EXTRA_CXX_FLAGS " -D LEAN_AUTO_THREAD_FINALIZATION")
|
||||
endif()
|
||||
|
||||
if(LLVM)
|
||||
if(NOT (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND CMAKE_C_COMPILER_ID STREQUAL "Clang"))
|
||||
message(FATAL_ERROR "LLVM=ON must be used with clang. Set `CMAKE_CXX_COMPILER` and `CMAKE_C_COMPILER` accordingly.")
|
||||
endif()
|
||||
message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}")
|
||||
message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}")
|
||||
|
||||
include_directories(${LLVM_INCLUDE_DIRS})
|
||||
string(APPEND LEAN_EXTRA_CXX_FLAGS " -D LEAN_LLVM")
|
||||
else()
|
||||
#message(WARNING "Disabling LLVM support. JIT compilation will not be available")
|
||||
endif()
|
||||
|
||||
# Set Module Path
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules")
|
||||
|
||||
|
|
@ -263,9 +250,44 @@ find_package(PythonInterp)
|
|||
|
||||
include_directories(${CMAKE_BINARY_DIR}/include)
|
||||
|
||||
# Pick up `llvm-config` to setup LLVM flags.
|
||||
if(LLVM)
|
||||
if(NOT LLVM_CONFIG) # look for `llvm-config` if not supplied
|
||||
message(STATUS "'-DLLVM_CONFIG=<path/to/llvm-config>' not passed as CMake flag, finding `llvm-config` via CMake...")
|
||||
find_program(LLVM_CONFIG "llvm-config")
|
||||
if(NOT LLVM_CONFIG) # check that it was found
|
||||
message(FATAL_ERROR "Unable to find 'llvm-config'")
|
||||
endif()
|
||||
endif()
|
||||
# check that we have 'llvm-config' version.
|
||||
message(STATUS "Executing 'llvm-config --version' at '${LLVM_CONFIG}' to check configuration.")
|
||||
execute_process(COMMAND ${LLVM_CONFIG} --version COMMAND_ERROR_IS_FATAL ANY)
|
||||
message(STATUS "Found 'llvm-config' as ${LLVM_CONFIG}")
|
||||
# -DLEAN_LLVM is used to conditionally compile Lean features that depend on LLVM
|
||||
string(APPEND LEAN_EXTRA_CXX_FLAGS " -D LEAN_LLVM")
|
||||
|
||||
execute_process(COMMAND ${LLVM_CONFIG} --ldflags OUTPUT_VARIABLE LLVM_CONFIG_LDFLAGS OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
execute_process(COMMAND ${LLVM_CONFIG} --libs OUTPUT_VARIABLE LLVM_CONFIG_LIBS OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
execute_process(COMMAND ${LLVM_CONFIG} --libdir OUTPUT_VARIABLE LLVM_CONFIG_LIBDIR OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
execute_process(COMMAND ${LLVM_CONFIG} --includedir OUTPUT_VARIABLE LLVM_CONFIG_INCLUDEDIR OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
execute_process(COMMAND ${LLVM_CONFIG} --cxxflags OUTPUT_VARIABLE LLVM_CONFIG_CXXFLAGS OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
execute_process(COMMAND ${LLVM_CONFIG} --system-libs OUTPUT_VARIABLE LLVM_CONFIG_SYSTEM_LIBS OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
message(STATUS "llvm-config: libdir '${LLVM_CONFIG_LIBDIR}' | ldflags '${LLVM_CONFIG_LDFLAGS}' | libs '${LLVM_CONFIG_LIBS}' | system libs '${LLVM_CONFIG_SYSTEM_LIBS}' | cxxflags: ${LLVM_CONFIG_CXXFLAGS} | includedir: ${LLVM_CONFIG_INCLUDEDIR}")
|
||||
else()
|
||||
message(WARNING "Disabling LLVM support")
|
||||
endif()
|
||||
|
||||
# libleancpp/Lean as well as libleanrt/Init are cyclically dependent. This works by default on macOS, which also doesn't like
|
||||
# the linker flags necessary on other platforms.
|
||||
# Furthermore, add LLVM flags into the list of flags we need when linking.
|
||||
# when using shared libraries, set the `rpath` to help the dynamic loader
|
||||
if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
||||
if(LLVM) # link to Zlib because LLVM depends on it.
|
||||
find_package(ZLIB REQUIRED)
|
||||
message(STATUS "ZLIB_LIBRARY: ${ZLIB_LIBRARY}")
|
||||
cmake_path(GET ZLIB_LIBRARY PARENT_PATH ZLIB_LIBRARY_PARENT_PATH)
|
||||
string(APPEND LEAN_EXTRA_LINKER_FLAGS " -L ${ZLIB_LIBRARY_PARENT_PATH}")
|
||||
endif()
|
||||
string(APPEND LEANC_STATIC_LINKER_FLAGS " -lleancpp -lInit -lLean -lleanrt")
|
||||
elseif(${CMAKE_SYSTEM_NAME} MATCHES "Emscripten")
|
||||
string(APPEND LEANC_STATIC_LINKER_FLAGS " -lleancpp -lInit -lLean -lnodefs.js -lleanrt")
|
||||
|
|
@ -282,6 +304,27 @@ endif()
|
|||
string(APPEND LEANC_STATIC_LINKER_FLAGS " ${LEAN_CXX_STDLIB}")
|
||||
string(APPEND LEANSHARED_LINKER_FLAGS " ${LEAN_CXX_STDLIB}")
|
||||
|
||||
if(LLVM)
|
||||
# Here, we perform a replacement of `llvm-host` with `llvm`. This is necessary for our cross-compile
|
||||
# builds in `script/prepare-llvm-*.sh`.
|
||||
# - Recall that the host's copy of LLVM binaries and libraries is at
|
||||
# `llvm-host`, and the target's copy of LLVM binaries and libraries is at
|
||||
# `llvm`.
|
||||
# - In an ideal world, we would run the target's `llvm/bin/llvm-config` and get the corrct link options for the target
|
||||
# (e.g. `-Lllvm/lib/libLLVM`.)
|
||||
# - However, the target's `llvm/bin/llvm-config` has a different target
|
||||
# triple from the host, and thus cannot be run on the host.
|
||||
# - So, we run the host `llvm-host/bin/llvm-config` from which we pick up
|
||||
# compiler options, and change the output of the host to point to the target.
|
||||
# - In particular, `host/bin/llvm-config` produces flags like `-Lllvm-host/lib/libLLVM`, while
|
||||
# we need the path to be `-Lllvm/lib/libLLVM`. Thus, we perform this replacement here.
|
||||
string(APPEND LEANSHARED_LINKER_FLAGS " -L${LLVM_CONFIG_LIBDIR} ${LLVM_CONFIG_LDFLAGS} ${LLVM_CONFIG_LIBS} ${LLVM_CONFIG_SYSTEM_LIBS}")
|
||||
string(REPLACE "llvm-host" "llvm" LEANSHARED_LINKER_FLAGS ${LEANSHARED_LINKER_FLAGS})
|
||||
set(APPEND LEAN_EXTRA_CXX_FLAGS " -I${LLVM_CONFIG_INCLUDEDIR}")
|
||||
string(REPLACE "llvm-host" "llvm" LEAN_EXTRA_CXX_FLAGS ${LEAN_EXTRA_CXX_FLAGS})
|
||||
message(VERBOSE "leanshared linker flags: '${LEANSHARED_LINKER_FLAGS}' | lean extra cxx flags '${LEAN_EXTR_CXX_FLAGS}'")
|
||||
endif()
|
||||
|
||||
# get rid of unused parts of C++ stdlib
|
||||
if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
||||
string(APPEND LEANSHARED_LINKER_FLAGS " -Wl,-dead_strip")
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ import Lean.Compiler.IR.ExpandResetReuse
|
|||
import Lean.Compiler.IR.UnboxResult
|
||||
import Lean.Compiler.IR.ElimDeadBranches
|
||||
import Lean.Compiler.IR.EmitC
|
||||
import Lean.Compiler.IR.EmitLLVM
|
||||
import Lean.Compiler.IR.CtorLayout
|
||||
import Lean.Compiler.IR.Sorry
|
||||
|
||||
|
|
|
|||
0
src/Lean/Compiler/IR/EmitLLVM.lean
Normal file
0
src/Lean/Compiler/IR/EmitLLVM.lean
Normal file
350
src/Lean/Compiler/IR/LLVMBindings.lean
Normal file
350
src/Lean/Compiler/IR/LLVMBindings.lean
Normal file
|
|
@ -0,0 +1,350 @@
|
|||
/-
|
||||
Copyright (c) 2022 Microsoft Corporation. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
Authors: Siddharth Bhat
|
||||
-/
|
||||
|
||||
namespace LLVM
|
||||
/-!
|
||||
This file defines bindings for LLVM. The main mechanisms
|
||||
are to:
|
||||
- Mirror the values of C enumerations.
|
||||
- Create opaque values for LLVM's pointer based API
|
||||
- Write bindings that are `IO` based, which mutate the underlying in-memory
|
||||
data structures to build IR.
|
||||
-/
|
||||
|
||||
-- https://github.com/llvm/llvm-project/blob/c3e073bcbdc523b0f758d44a89a6333e38bff863/llvm/include/llvm-c/TargetMachine.h#L64
|
||||
structure CodegenFileType where
|
||||
private mk :: val : UInt64
|
||||
|
||||
def CodegenFileType.AssemblyFile : CodegenFileType := { val := 0 }
|
||||
def CodegenFileType.ObjectFile : CodegenFileType := { val := 1 }
|
||||
|
||||
-- https://github.com/llvm/llvm-project/blob/c3e073bcbdc523b0f758d44a89a6333e38bff863/llvm/include/llvm-c/Core.h#L290
|
||||
structure IntPredicate where
|
||||
private mk :: val : UInt64
|
||||
|
||||
def IntPredicate.EQ : IntPredicate := { val := 32 }
|
||||
def IntPredicate.NE : IntPredicate := { val := IntPredicate.EQ.val + 1 }
|
||||
def IntPredicate.UGT : IntPredicate := { val := IntPredicate.NE.val + 1 }
|
||||
|
||||
structure BasicBlock (ctx : Context) where
|
||||
private mk :: ptr : USize
|
||||
instance : Nonempty (BasicBlock ctx) := ⟨{ ptr := default }⟩
|
||||
|
||||
structure Builder (ctx : Context) where
|
||||
private mk :: ptr : USize
|
||||
instance : Nonempty (Builder ctx) := ⟨{ ptr := default }⟩
|
||||
|
||||
structure Context where
|
||||
private mk :: ptr : USize
|
||||
instance : Nonempty Context := ⟨{ ptr := default }⟩
|
||||
|
||||
structure LLVMType (ctx : Context) where
|
||||
private mk :: ptr : USize
|
||||
instance : Nonempty (LLVMType ctx) := ⟨{ ptr := default }⟩
|
||||
|
||||
structure MemoryBuffer (ctx : Context) where
|
||||
private mk :: ptr : USize
|
||||
instance : Nonempty (MemoryBuffer ctx) := ⟨{ ptr := default }⟩
|
||||
|
||||
structure Module (ctx : Context) where
|
||||
private mk :: ptr : USize
|
||||
instance : Nonempty (Module ctx) := ⟨{ ptr := default }⟩
|
||||
|
||||
structure PassManager (ctx : Context) where
|
||||
private mk :: ptr : USize
|
||||
instance : Nonempty (PassManager ctx) := ⟨{ ptr := default }⟩
|
||||
|
||||
structure PassManagerBuilder (ctx : Context) where
|
||||
private mk :: ptr : USize
|
||||
instance : Nonempty (PassManagerBuilder ctx) := ⟨{ ptr := default }⟩
|
||||
|
||||
structure Target (ctx : Context) where
|
||||
private mk :: ptr : USize
|
||||
instance : Nonempty (Target ctx) := ⟨{ ptr := default }⟩
|
||||
|
||||
structure TargetMachine (ctx : Context) where
|
||||
private mk :: ptr : USize
|
||||
instance : Nonempty (TargetMachine ctx) := ⟨{ ptr := default }⟩
|
||||
|
||||
structure Value (ctx : Context) where
|
||||
private mk :: ptr : USize
|
||||
instance : Nonempty (Value ctx) := ⟨{ ptr := default }⟩
|
||||
|
||||
@[extern "lean_llvm_create_context"]
|
||||
opaque createContext : BaseIO (Context)
|
||||
|
||||
@[extern "lean_llvm_create_module"]
|
||||
opaque createModule (ctx : Context) (name : @&String) : BaseIO (Module ctx)
|
||||
|
||||
@[extern "lean_llvm_module_to_string"]
|
||||
opaque moduleToString (m : Module ctx) : BaseIO String
|
||||
|
||||
@[extern "lean_llvm_write_bitcode_to_file"]
|
||||
opaque writeBitcodeToFile (m : Module ctx) (path : @&String) : BaseIO Unit
|
||||
|
||||
@[extern "lean_llvm_add_function"]
|
||||
opaque addFunction (m : Module ctx) (name : @&String) (type : LLVMType ctx) : BaseIO (Value ctx)
|
||||
|
||||
@[extern "lean_llvm_get_named_function"]
|
||||
opaque getNamedFunction (m : Module ctx) (name : @&String) : BaseIO (Option (Value ctx))
|
||||
|
||||
@[extern "lean_llvm_add_global"]
|
||||
opaque addGlobal (m : Module ctx) (name : @&String) (type : LLVMType ctx) : BaseIO (Value ctx)
|
||||
|
||||
@[extern "lean_llvm_get_named_global"]
|
||||
opaque getNamedGlobal (m : Module ctx) (name : @&String) : BaseIO (Option (Value ctx))
|
||||
|
||||
@[extern "lean_llvm_build_global_string"]
|
||||
opaque buildGlobalString (builder : Builder ctx) (value : @&String) (name : @&String := "") : BaseIO (Value ctx)
|
||||
|
||||
@[extern "lean_llvm_set_initializer"]
|
||||
opaque setInitializer (glbl : Value ctx) (val : Value ctx) : BaseIO Unit
|
||||
|
||||
@[extern "lean_llvm_function_type"]
|
||||
opaque functionType (retty : LLVMType ctx) (args : @&Array (LLVMType ctx)) (isVarArg : Bool := false) : BaseIO (LLVMType ctx)
|
||||
|
||||
@[extern "lean_llvm_void_type_in_context"]
|
||||
opaque voidType (ctx : Context) : BaseIO (LLVMType ctx)
|
||||
|
||||
@[extern "lean_llvm_int_type_in_context"]
|
||||
opaque intTypeInContext (ctx : Context) (width : UInt64) : BaseIO (LLVMType ctx)
|
||||
|
||||
@[extern "lean_llvm_float_type_in_context"]
|
||||
opaque floatTypeInContext (ctx : Context) : BaseIO (LLVMType ctx)
|
||||
|
||||
@[extern "lean_llvm_double_type_in_context"]
|
||||
opaque doubleTypeInContext (ctx : Context) : BaseIO (LLVMType ctx)
|
||||
|
||||
@[extern "lean_llvm_pointer_type"]
|
||||
opaque pointerType (elemty : LLVMType ctx) : BaseIO (LLVMType ctx)
|
||||
|
||||
@[extern "lean_llvm_array_type"]
|
||||
opaque arrayType (elemty : LLVMType ctx) (nelem : UInt64) : BaseIO (LLVMType ctx)
|
||||
|
||||
@[extern "lean_llvm_const_array"]
|
||||
opaque constArray (elemty : LLVMType ctx) (vals : @&Array (Value ctx)) : BaseIO (LLVMType ctx)
|
||||
|
||||
-- `constString` provides a `String` as a constant array of element type `i8`
|
||||
@[extern "lean_llvm_const_string"]
|
||||
opaque constString (ctx : Context) (str : @&String) : BaseIO (Value ctx)
|
||||
|
||||
@[extern "lean_llvm_const_pointer_null"]
|
||||
opaque constPointerNull (elemty : LLVMType ctx) : BaseIO (Value ctx)
|
||||
|
||||
@[extern "lean_llvm_get_undef"]
|
||||
opaque getUndef (elemty : LLVMType ctx) : BaseIO (Value ctx)
|
||||
|
||||
@[extern "lean_llvm_create_builder_in_context"]
|
||||
opaque createBuilderInContext (ctx : Context) : BaseIO (Builder ctx)
|
||||
|
||||
@[extern "lean_llvm_append_basic_block_in_context"]
|
||||
opaque appendBasicBlockInContext (ctx : Context) (fn : Value ctx) (name : @&String) : BaseIO (BasicBlock ctx)
|
||||
|
||||
@[extern "lean_llvm_position_builder_at_end"]
|
||||
opaque positionBuilderAtEnd (builder : Builder ctx) (bb : BasicBlock ctx) : BaseIO Unit
|
||||
|
||||
@[extern "lean_llvm_build_call"]
|
||||
opaque buildCall (builder : Builder ctx) (fn : Value ctx) (args : @&Array (Value ctx)) (name : @&String := "") : BaseIO (Value ctx)
|
||||
|
||||
@[extern "lean_llvm_set_tail_call"]
|
||||
opaque setTailCall (fn : Value ctx) (istail : Bool) : BaseIO Unit
|
||||
|
||||
@[extern "lean_llvm_build_cond_br"]
|
||||
opaque buildCondBr (builder : Builder ctx) (if_ : Value ctx) (thenbb : BasicBlock ctx) (elsebb : BasicBlock ctx) : BaseIO (Value ctx)
|
||||
|
||||
@[extern "lean_llvm_build_br"]
|
||||
opaque buildBr (builder : Builder ctx) (bb : BasicBlock ctx) : BaseIO (Value ctx)
|
||||
|
||||
@[extern "lean_llvm_build_alloca"]
|
||||
opaque buildAlloca (builder : Builder ctx) (ty : LLVMType ctx) (name : @&String := "") : BaseIO (Value ctx)
|
||||
|
||||
@[extern "lean_llvm_build_load"]
|
||||
opaque buildLoad (builder : Builder ctx) (val : Value ctx) (name : @&String := "") : BaseIO (Value ctx)
|
||||
|
||||
@[extern "lean_llvm_build_store"]
|
||||
opaque buildStore (builder : Builder ctx) (val : Value ctx) (store_loc_ptr : Value ctx) : BaseIO Unit
|
||||
|
||||
@[extern "lean_llvm_build_ret"]
|
||||
opaque buildRet (builder : Builder ctx) (val : Value ctx) : BaseIO (Value ctx)
|
||||
|
||||
@[extern "lean_llvm_build_unreachable"]
|
||||
opaque buildUnreachable (builder : Builder ctx) : BaseIO (Value ctx)
|
||||
|
||||
@[extern "lean_llvm_build_gep"]
|
||||
opaque buildGEP (builder : Builder ctx) (base : Value ctx) (ixs : @&Array (Value ctx)) (name : @&String := "") : BaseIO (Value ctx)
|
||||
|
||||
@[extern "lean_llvm_build_inbounds_gep"]
|
||||
opaque buildInBoundsGEP (builder : Builder ctx) (base : Value ctx) (ixs : @&Array (Value ctx)) (name : @&String := "") : BaseIO (Value ctx)
|
||||
|
||||
@[extern "lean_llvm_build_pointer_cast"]
|
||||
opaque buildPointerCast (builder : Builder ctx) (val : Value ctx) (destTy : LLVMType ctx) (name : @&String := "") : BaseIO (Value ctx)
|
||||
|
||||
@[extern "lean_llvm_build_sext"]
|
||||
opaque buildSext (builder : Builder ctx) (val : Value ctx) (destTy : LLVMType ctx) (name : @&String := "") : BaseIO (Value ctx)
|
||||
|
||||
@[extern "lean_llvm_build_zext"]
|
||||
opaque buildZext (builder : Builder ctx) (val : Value ctx) (destTy : LLVMType ctx) (name : @&String := "") : BaseIO (Value ctx)
|
||||
|
||||
@[extern "lean_llvm_build_sext_or_trunc"]
|
||||
opaque buildSextOrTrunc (builder : Builder ctx) (val : Value ctx) (destTy : LLVMType ctx) (name : @&String := "") : BaseIO (Value ctx)
|
||||
|
||||
@[extern "lean_llvm_build_switch"]
|
||||
opaque buildSwitch (builder : Builder ctx) (val : Value ctx) (elseBB : BasicBlock ctx) (numCasesHint : UInt64) : BaseIO (Value ctx)
|
||||
|
||||
@[extern "lean_llvm_build_ptr_to_int"]
|
||||
opaque buildPtrToInt (builder : Builder ctx) (ptr : Value ctx) (destTy : LLVMType ctx) (name : @&String := "") : BaseIO (Value ctx)
|
||||
|
||||
@[extern "lean_llvm_build_mul"]
|
||||
opaque buildMul (builder : Builder ctx) (x y : Value ctx) (name : @&String) : BaseIO (Value ctx)
|
||||
|
||||
@[extern "lean_llvm_build_add"]
|
||||
opaque buildAdd (builder : Builder ctx) (x y : Value ctx) (name : @&String) : BaseIO (Value ctx)
|
||||
|
||||
@[extern "lean_llvm_build_sub"]
|
||||
opaque buildSub (builder : Builder ctx) (x y : Value ctx) (name : @&String := "") : BaseIO (Value ctx)
|
||||
|
||||
@[extern "lean_llvm_build_not"]
|
||||
opaque buildNot (builder : Builder ctx) (x : Value ctx) (name : @&String := "") : BaseIO (Value ctx)
|
||||
|
||||
@[extern "lean_llvm_build_icmp"]
|
||||
opaque buildICmp (builder : Builder ctx) (predicate : IntPredicate) (x y : Value ctx) (name : @&String := "") : BaseIO (Value ctx)
|
||||
|
||||
@[extern "lean_llvm_add_case"]
|
||||
opaque addCase (switch onVal : Value ctx) (destBB : BasicBlock ctx) : BaseIO Unit
|
||||
|
||||
@[extern "lean_llvm_get_insert_block"]
|
||||
opaque getInsertBlock (builder : Builder ctx) : BaseIO (BasicBlock ctx)
|
||||
|
||||
@[extern "lean_llvm_clear_insertion_position"]
|
||||
opaque clearInsertionPosition (builder : Builder ctx) : BaseIO Unit
|
||||
|
||||
@[extern "lean_llvm_get_basic_block_parent"]
|
||||
opaque getBasicBlockParent (bb : BasicBlock ctx) : BaseIO (Value ctx)
|
||||
|
||||
@[extern "lean_llvm_type_of"]
|
||||
opaque typeOf (val : Value ctx) : BaseIO (LLVMType ctx)
|
||||
|
||||
@[extern "lean_llvm_const_int"]
|
||||
opaque constInt (intty : LLVMType ctx) (value : UInt64) (signExtend : @Bool := false) : BaseIO (Value ctx)
|
||||
|
||||
@[extern "lean_llvm_print_module_to_string"]
|
||||
opaque printModuletoString (mod : Module ctx) : BaseIO (String)
|
||||
|
||||
@[extern "lean_llvm_print_module_to_file"]
|
||||
opaque printModuletoFile (mod : Module ctx) (file : @&String) : BaseIO Unit
|
||||
|
||||
@[extern "llvm_count_params"]
|
||||
opaque countParams (fn : Value ctx) : UInt64
|
||||
|
||||
@[extern "llvm_get_param"]
|
||||
opaque getParam (fn : Value ctx) (ix : UInt64) : BaseIO (Value ctx)
|
||||
|
||||
@[extern "lean_llvm_create_memory_buffer_with_contents_of_file"]
|
||||
opaque createMemoryBufferWithContentsOfFile (path : @&String) : BaseIO (MemoryBuffer ctx)
|
||||
|
||||
@[extern "lean_llvm_parse_bitcode"]
|
||||
opaque parseBitcode (ctx : Context) (membuf : MemoryBuffer ctx) : BaseIO (Module ctx)
|
||||
|
||||
@[extern "lean_llvm_link_modules"]
|
||||
opaque linkModules (dest : Module ctx) (src : Module ctx) : BaseIO Unit
|
||||
|
||||
@[extern "lean_llvm_get_default_target_triple"]
|
||||
opaque getDefaultTargetTriple : BaseIO String
|
||||
|
||||
@[extern "lean_llvm_get_target_from_triple"]
|
||||
opaque getTargetFromTriple (triple : @&String) : BaseIO (Target ctx)
|
||||
|
||||
@[extern "lean_llvm_create_target_machine"]
|
||||
opaque createTargetMachine (target : Target ctx) (tripleStr : @&String) (cpu : @&String) (features : @&String) : BaseIO (TargetMachine ctx)
|
||||
|
||||
@[extern "lean_llvm_target_machine_emit_to_file"]
|
||||
opaque targetMachineEmitToFile (targetMachine : TargetMachine ctx) (module : Module ctx) (filepath : @&String) (codegenType : LLVM.CodegenFileType) : BaseIO Unit
|
||||
|
||||
@[extern "lean_llvm_create_pass_manager"]
|
||||
opaque createPassManager : BaseIO (PassManager ctx)
|
||||
|
||||
@[extern "lean_llvm_dispose_pass_manager"]
|
||||
opaque disposePassManager (pm : PassManager ctx) : BaseIO Unit
|
||||
|
||||
@[extern "lean_llvm_run_pass_manager"]
|
||||
opaque runPassManager (pm : PassManager ctx) (mod : Module ctx): BaseIO Unit
|
||||
|
||||
@[extern "lean_llvm_create_pass_manager_builder"]
|
||||
opaque createPassManagerBuilder : BaseIO (PassManagerBuilder ctx)
|
||||
|
||||
@[extern "lean_llvm_dispose_pass_manager_builder"]
|
||||
opaque disposePassManagerBuilder (pmb : PassManagerBuilder ctx) : BaseIO Unit
|
||||
|
||||
@[extern "lean_llvm_pass_manager_builder_set_opt_level"]
|
||||
opaque PassManagerBuilder.setOptLevel (pmb : PassManagerBuilder ctx) (optLevel : unsigned) : BaseIO Unit
|
||||
|
||||
@[extern "lean_llvm_pass_manager_builder_populate_module_pass_manager"]
|
||||
opaque PassManagerBuilder.populateModulePassManager (pmb : PassManagerBuilder ctx) (pm : PassManager ctx): BaseIO Unit
|
||||
|
||||
@[extern "lean_llvm_dispose_target_machine"]
|
||||
opaque disposeTargetMachine (tm : TargetMachine ctx) : BaseIO Unit
|
||||
|
||||
@[extern "lean_llvm_dispose_module"]
|
||||
opaque disposeModule (m : Module ctx) : BaseIO Unit
|
||||
|
||||
|
||||
-- Helper to add a function if it does not exist, and to return the function handle if it does.
|
||||
def getOrAddFunction(m : Module ctx) (name : String) (type : LLVMType ctx) : BaseIO (Value ctx) := do
|
||||
match (← getNamedFunction m name) with
|
||||
| .some fn => return fn
|
||||
| .none => addFunction m name type
|
||||
|
||||
def getOrAddGlobal(m : Module ctx) (name : String) (type : LLVMType ctx) : BaseIO (Value ctx) := do
|
||||
match (← getNamedGlobal m name) with
|
||||
| .some fn => return fn
|
||||
| .none => addGlobal m name type
|
||||
|
||||
|
||||
def i1Type (ctx : LLVM.Context) : BaseIO (LLVM.LLVMType ctx) :=
|
||||
LLVM.intTypeInContext ctx 1
|
||||
|
||||
def i8Type (ctx : LLVM.Context) : BaseIO (LLVM.LLVMType ctx) :=
|
||||
LLVM.intTypeInContext ctx 8
|
||||
|
||||
def i16Type (ctx : LLVM.Context) : BaseIO (LLVM.LLVMType ctx) :=
|
||||
LLVM.intTypeInContext ctx 16
|
||||
|
||||
def i32Type (ctx : LLVM.Context) : BaseIO (LLVM.LLVMType ctx) :=
|
||||
LLVM.intTypeInContext ctx 32
|
||||
|
||||
def i64Type (ctx : LLVM.Context) : BaseIO (LLVM.LLVMType ctx) :=
|
||||
LLVM.intTypeInContext ctx 64
|
||||
|
||||
def voidPtrType (ctx : LLVM.Context) : BaseIO (LLVM.LLVMType ctx) :=
|
||||
do LLVM.pointerType (← LLVM.intTypeInContext ctx 8)
|
||||
|
||||
def i8PtrType (ctx : LLVM.Context) : BaseIO (LLVM.LLVMType ctx) :=
|
||||
voidPtrType ctx
|
||||
|
||||
def constTrue (ctx : Context) : BaseIO (Value ctx) :=
|
||||
do constInt (← i1Type ctx) 1 (signExtend := false)
|
||||
|
||||
def constFalse (ctx : Context) : BaseIO (Value ctx) :=
|
||||
do constInt (← i1Type ctx) 0 (signExtend := false)
|
||||
|
||||
def constInt' (ctx : Context) (width : UInt64) (value : UInt64) (signExtend : Bool := false) : BaseIO (Value ctx) :=
|
||||
do constInt (← LLVM.intTypeInContext ctx width) value signExtend
|
||||
|
||||
def constInt1 (ctx : Context) (value : UInt64) (signExtend : Bool := false) : BaseIO (Value ctx) :=
|
||||
constInt' ctx 1 value signExtend
|
||||
|
||||
def constInt8 (ctx : Context) (value : UInt64) (signExtend : Bool := false) : BaseIO (Value ctx) :=
|
||||
constInt' ctx 8 value signExtend
|
||||
|
||||
def constInt32 (ctx : Context) (value : UInt64) (signExtend : Bool := false) : BaseIO (Value ctx) :=
|
||||
constInt' ctx 32 value signExtend
|
||||
|
||||
def constInt64 (ctx : Context) (value : UInt64) (signExtend : Bool := false) : BaseIO (Value ctx) :=
|
||||
constInt' ctx 64 value signExtend
|
||||
|
||||
def constIntUnsigned (ctx : Context) (value : UInt64) (signExtend : Bool := false) : BaseIO (Value ctx) :=
|
||||
constInt' ctx 64 value signExtend
|
||||
end LLVM
|
||||
|
|
@ -6,4 +6,4 @@ add_library(compiler OBJECT init_module.cpp ## New
|
|||
export_attribute.cpp extern_attribute.cpp
|
||||
borrowed_annotation.cpp init_attribute.cpp eager_lambda_lifting.cpp
|
||||
struct_cases_on.cpp find_jp.cpp ir.cpp implemented_by_attribute.cpp
|
||||
ir_interpreter.cpp)
|
||||
ir_interpreter.cpp llvm.cpp)
|
||||
|
|
|
|||
1301
src/library/compiler/llvm.cpp
Normal file
1301
src/library/compiler/llvm.cpp
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Add table
Reference in a new issue