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:
Siddharth 2022-11-21 00:50:01 -08:00 committed by GitHub
parent 1b73fa3fa1
commit 4d47c8abc6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 1718 additions and 18 deletions

View file

@ -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

View file

@ -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 // {

View file

@ -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:-}'"

View file

@ -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

View file

@ -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++"

View file

@ -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")

View file

@ -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

View file

View 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

View file

@ -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)

File diff suppressed because it is too large Load diff