ability to disable llvm at compile time (#1433)

ability to disable llvm at compile time
This commit is contained in:
alex_s168
2024-09-12 13:36:00 +02:00
committed by GitHub
parent eaa419a48d
commit d376ee6671
8 changed files with 434 additions and 188 deletions

View File

@@ -63,6 +63,7 @@ set(C3_LLVM_VERSION "auto" CACHE STRING "Use LLVM version [default: auto]")
option(C3_USE_MIMALLOC "Use built-in mimalloc" OFF)
option(C3_USE_TB "Use TB" OFF)
set(C3_MIMALLOC_TAG "v1.7.3" CACHE STRING "Used version of mimalloc")
option(C3_WITH_LLVM "Build with LLVM" ON)
set(C3_USE_MIMALLOC OFF)
if(C3_USE_MIMALLOC)
@@ -80,9 +81,11 @@ endif()
if (NOT WIN32)
find_package(CURL)
endif()
if (NOT C3_LLVM_VERSION STREQUAL "auto")
if (${C3_LLVM_VERSION} VERSION_LESS 17 OR ${C3_LLVM_VERSION} VERSION_GREATER 20)
message(FATAL_ERROR "LLVM ${C3_LLVM_VERSION} is not supported!")
if(C3_WITH_LLVM)
if (NOT C3_LLVM_VERSION STREQUAL "auto")
if (${C3_LLVM_VERSION} VERSION_LESS 17 OR ${C3_LLVM_VERSION} VERSION_GREATER 20)
message(FATAL_ERROR "LLVM ${C3_LLVM_VERSION} is not supported!")
endif()
endif()
endif()
@@ -112,113 +115,115 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
)
endif(C3_ENABLE_CLANGD_LSP)
if(CMAKE_C_COMPILER_ID STREQUAL "MSVC")
if (C3_LLVM_VERSION STREQUAL "auto")
set(C3_LLVM_VERSION "18")
endif()
FetchContent_Declare(
LLVM_Windows
URL https://github.com/c3lang/win-llvm/releases/download/llvm_18_1_8_with_rt/llvm-18.1.8-windows-amd64-msvc17-libcmt.7z
)
FetchContent_Declare(
LLVM_Windows_debug
URL https://github.com/c3lang/win-llvm/releases/download/llvm_18_1_8_with_rt/llvm-18.1.8-windows-amd64-msvc17-libcmt-dbg.7z
)
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
message("Loading Windows LLVM debug libraries, this may take a while...")
FetchContent_MakeAvailable(LLVM_Windows_debug)
set(llvm_dir ${llvm_windows_debug_SOURCE_DIR})
else()
message("Loading Windows LLVM libraries, this may take a while...")
FetchContent_MakeAvailable(LLVM_Windows)
set(llvm_dir ${llvm_windows_SOURCE_DIR})
endif()
set(CMAKE_SYSTEM_PREFIX_PATH ${llvm_dir} ${CMAKE_SYSTEM_PREFIX_PATH})
if(C3_WITH_LLVM)
if(CMAKE_C_COMPILER_ID STREQUAL "MSVC")
if (C3_LLVM_VERSION STREQUAL "auto")
set(C3_LLVM_VERSION "18")
endif()
FetchContent_Declare(
LLVM_Windows
URL https://github.com/c3lang/win-llvm/releases/download/llvm_18_1_8_with_rt/llvm-18.1.8-windows-amd64-msvc17-libcmt.7z
)
FetchContent_Declare(
LLVM_Windows_debug
URL https://github.com/c3lang/win-llvm/releases/download/llvm_18_1_8_with_rt/llvm-18.1.8-windows-amd64-msvc17-libcmt-dbg.7z
)
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
message("Loading Windows LLVM debug libraries, this may take a while...")
FetchContent_MakeAvailable(LLVM_Windows_debug)
set(llvm_dir ${llvm_windows_debug_SOURCE_DIR})
else()
message("Loading Windows LLVM libraries, this may take a while...")
FetchContent_MakeAvailable(LLVM_Windows)
set(llvm_dir ${llvm_windows_SOURCE_DIR})
endif()
set(CMAKE_SYSTEM_PREFIX_PATH ${llvm_dir} ${CMAKE_SYSTEM_PREFIX_PATH})
find_package(LLVM REQUIRED CONFIG)
find_package(LLD REQUIRED CONFIG)
else()
if (NOT C3_LLVM_VERSION STREQUAL "auto")
find_package(LLVM ${C3_LLVM_VERSION} REQUIRED CONFIG)
else()
find_package(LLVM REQUIRED CONFIG)
find_package(LLD REQUIRED CONFIG)
else()
if (NOT C3_LLVM_VERSION STREQUAL "auto")
find_package(LLVM ${C3_LLVM_VERSION} REQUIRED CONFIG)
else()
find_package(LLVM REQUIRED CONFIG)
endif()
endif()
endif()
message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}")
message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}")
message(STATUS "Libraries located in: ${LLVM_LIBRARY_DIRS}")
message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}")
message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}")
message(STATUS "Libraries located in: ${LLVM_LIBRARY_DIRS}")
if (NOT LLVM_PACKAGE_VERSION VERSION_GREATER_EQUAL 15.0)
message(FATAL_ERROR "LLVM version 15.0 or later is required.")
endif()
if (NOT LLVM_PACKAGE_VERSION VERSION_GREATER_EQUAL 15.0)
message(FATAL_ERROR "LLVM version 15.0 or later is required.")
endif()
if(LLVM_ENABLE_RTTI)
message(STATUS "LLVM was built with RTTI")
else()
message(STATUS "LLVM was not built with RTTI")
endif()
if(LLVM_ENABLE_RTTI)
message(STATUS "LLVM was built with RTTI")
else()
message(STATUS "LLVM was not built with RTTI")
endif()
string(REPLACE "." ";" VERSION_LIST ${LLVM_PACKAGE_VERSION})
list(GET VERSION_LIST 0 LLVM_MAJOR_VERSION)
string(REPLACE "." ";" VERSION_LIST ${LLVM_PACKAGE_VERSION})
list(GET VERSION_LIST 0 LLVM_MAJOR_VERSION)
include_directories(${LLVM_INCLUDE_DIRS})
link_directories(${LLVM_LIBRARY_DIRS})
add_definitions(${LLVM_DEFINITIONS})
include_directories(${LLVM_INCLUDE_DIRS})
link_directories(${LLVM_LIBRARY_DIRS})
add_definitions(${LLVM_DEFINITIONS})
if(NOT C3_LINK_DYNAMIC)
set(LLVM_LINK_COMPONENTS
AllTargetsAsmParsers
AllTargetsCodeGens
AllTargetsDescs
AllTargetsDisassemblers
AllTargetsInfos
Analysis
AsmPrinter
BitReader
Core
DebugInfoPDB
InstCombine
IrReader
LibDriver
Linker
LTO
MC
MCDisassembler
native
nativecodegen
Object
Option
ScalarOpts
Support
Target
TransformUtils
WindowsManifest
WindowsDriver
)
if(NOT C3_LINK_DYNAMIC)
set(LLVM_LINK_COMPONENTS
AllTargetsAsmParsers
AllTargetsCodeGens
AllTargetsDescs
AllTargetsDisassemblers
AllTargetsInfos
Analysis
AsmPrinter
BitReader
Core
DebugInfoPDB
InstCombine
IrReader
LibDriver
Linker
LTO
MC
MCDisassembler
native
nativecodegen
Object
Option
ScalarOpts
Support
Target
TransformUtils
WindowsManifest
WindowsDriver
)
llvm_map_components_to_libnames(llvm_libs ${LLVM_LINK_COMPONENTS})
llvm_map_components_to_libnames(llvm_libs ${LLVM_LINK_COMPONENTS})
# These don't seem to be reliable on windows.
message(STATUS "using find_library")
find_library(LLD_COFF NAMES lldCOFF.lib lldCOFF.a liblldCOFF.a PATHS ${LLVM_LIBRARY_DIRS} NO_DEFAULT_PATH)
find_library(LLD_COMMON NAMES lldCommon.lib lldCommon.a liblldCommon.a PATHS ${LLVM_LIBRARY_DIRS} NO_DEFAULT_PATH)
find_library(LLD_ELF NAMES lldELF.lib lldELF.a liblldELF.a PATHS ${LLVM_LIBRARY_DIRS} NO_DEFAULT_PATH)
find_library(LLD_MACHO NAMES lldMachO.lib lldMachO.a liblldMachO.a PATHS ${LLVM_LIBRARY_DIRS} NO_DEFAULT_PATH)
find_library(LLD_MINGW NAMES lldMinGW.lib lldMinGW.a liblldMinGW.a PATHS ${LLVM_LIBRARY_DIRS} NO_DEFAULT_PATH)
find_library(LLD_WASM NAMES lldWasm.lib lldWasm.a liblldWasm.a PATHS ${LLVM_LIBRARY_DIRS} NO_DEFAULT_PATH)
else()
find_library(LLVM NAMES libLLVM.so PATHS ${LLVM_LIBRARY_DIRS} NO_DEFAULT_PATH)
set(llvm_libs ${LLVM})
# These don't seem to be reliable on windows.
message(STATUS "using find_library")
find_library(LLD_COFF NAMES lldCOFF.lib lldCOFF.a liblldCOFF.a PATHS ${LLVM_LIBRARY_DIRS} NO_DEFAULT_PATH)
find_library(LLD_COMMON NAMES lldCommon.lib lldCommon.a liblldCommon.a PATHS ${LLVM_LIBRARY_DIRS} NO_DEFAULT_PATH)
find_library(LLD_ELF NAMES lldELF.lib lldELF.a liblldELF.a PATHS ${LLVM_LIBRARY_DIRS} NO_DEFAULT_PATH)
find_library(LLD_MACHO NAMES lldMachO.lib lldMachO.a liblldMachO.a PATHS ${LLVM_LIBRARY_DIRS} NO_DEFAULT_PATH)
find_library(LLD_MINGW NAMES lldMinGW.lib lldMinGW.a liblldMinGW.a PATHS ${LLVM_LIBRARY_DIRS} NO_DEFAULT_PATH)
find_library(LLD_WASM NAMES lldWasm.lib lldWasm.a liblldWasm.a PATHS ${LLVM_LIBRARY_DIRS} NO_DEFAULT_PATH)
else()
find_library(LLVM NAMES libLLVM.so PATHS ${LLVM_LIBRARY_DIRS} NO_DEFAULT_PATH)
set(llvm_libs ${LLVM})
# These don't seem to be reliable on windows.
message(STATUS "using find_library")
find_library(LLD_COFF NAMES liblldCOFF.so PATHS ${LLVM_LIBRARY_DIRS} NO_DEFAULT_PATH)
find_library(LLD_COMMON NAMES liblldCommon.so PATHS ${LLVM_LIBRARY_DIRS} NO_DEFAULT_PATH)
find_library(LLD_ELF NAMES liblldELF.so PATHS ${LLVM_LIBRARY_DIRS} NO_DEFAULT_PATH)
find_library(LLD_MACHO NAMES liblldMachO.so PATHS ${LLVM_LIBRARY_DIRS} NO_DEFAULT_PATH)
find_library(LLD_MINGW NAMES liblldMinGW.so PATHS ${LLVM_LIBRARY_DIRS} NO_DEFAULT_PATH)
find_library(LLD_WASM NAMES liblldWasm.so PATHS ${LLVM_LIBRARY_DIRS} NO_DEFAULT_PATH)
# These don't seem to be reliable on windows.
message(STATUS "using find_library")
find_library(LLD_COFF NAMES liblldCOFF.so PATHS ${LLVM_LIBRARY_DIRS} NO_DEFAULT_PATH)
find_library(LLD_COMMON NAMES liblldCommon.so PATHS ${LLVM_LIBRARY_DIRS} NO_DEFAULT_PATH)
find_library(LLD_ELF NAMES liblldELF.so PATHS ${LLVM_LIBRARY_DIRS} NO_DEFAULT_PATH)
find_library(LLD_MACHO NAMES liblldMachO.so PATHS ${LLVM_LIBRARY_DIRS} NO_DEFAULT_PATH)
find_library(LLD_MINGW NAMES liblldMinGW.so PATHS ${LLVM_LIBRARY_DIRS} NO_DEFAULT_PATH)
find_library(LLD_WASM NAMES liblldWasm.so PATHS ${LLVM_LIBRARY_DIRS} NO_DEFAULT_PATH)
endif()
endif()
if (NOT(${CMAKE_BINARY_DIR} EQUAL ${CMAKE_SOURCE_DIR}))
@@ -226,36 +231,36 @@ if (NOT(${CMAKE_BINARY_DIR} EQUAL ${CMAKE_SOURCE_DIR}))
file(COPY ${CMAKE_SOURCE_DIR}/lib DESTINATION ${CMAKE_BINARY_DIR})
endif()
find_library(LLD_LOONG NAMES libLLVMLoongArchCodeGen.lib libLLVMLoongArchAsmParser.lib libLLVMLoongArchCodeGen.a libLLVMLoongArchAsmParser.a PATHS ${LLVM_LIBRARY_DIRS} NO_DEFAULT_PATH)
set(lld_libs
${LLD_COFF}
${LLD_COMMON}
${LLD_WASM}
${LLD_MINGW}
${LLD_ELF}
${LLD_MACHO}
)
if (APPLE)
set(lld_libs ${lld_libs} xar)
find_file(RT_ASAN_DYNAMIC NAMES libclang_rt.asan_osx_dynamic.dylib PATHS "${LLVM_LIBRARY_DIRS}/clang/${LLVM_MAJOR_VERSION}/lib/darwin")
find_file(RT_TSAN_DYNAMIC NAMES libclang_rt.tsan_osx_dynamic.dylib PATHS "${LLVM_LIBRARY_DIRS}/clang/${LLVM_MAJOR_VERSION}/lib/darwin")
find_file(RT_UBSAN_DYNAMIC NAMES libclang_rt.ubsan_osx_dynamic.dylib PATHS "${LLVM_LIBRARY_DIRS}/clang/${LLVM_MAJOR_VERSION}/lib/darwin")
find_file(RT_LSAN_DYNAMIC NAMES libclang_rt.lsan_osx_dynamic.dylib PATHS "${LLVM_LIBRARY_DIRS}/clang/${LLVM_MAJOR_VERSION}/lib/darwin")
set(sanitizer_runtime_libraries
${RT_ASAN_DYNAMIC}
${RT_TSAN_DYNAMIC}
# Unused
# ${RT_UBSAN_DYNAMIC}
# ${RT_LSAN_DYNAMIC}
if(C3_WITH_LLVM)
find_library(LLD_LOONG NAMES libLLVMLoongArchCodeGen.lib libLLVMLoongArchAsmParser.lib libLLVMLoongArchCodeGen.a libLLVMLoongArchAsmParser.a PATHS ${LLVM_LIBRARY_DIRS} NO_DEFAULT_PATH)
set(lld_libs
${LLD_COFF}
${LLD_COMMON}
${LLD_WASM}
${LLD_MINGW}
${LLD_ELF}
${LLD_MACHO}
)
if (APPLE)
set(lld_libs ${lld_libs} xar)
find_file(RT_ASAN_DYNAMIC NAMES libclang_rt.asan_osx_dynamic.dylib PATHS "${LLVM_LIBRARY_DIRS}/clang/${LLVM_MAJOR_VERSION}/lib/darwin")
find_file(RT_TSAN_DYNAMIC NAMES libclang_rt.tsan_osx_dynamic.dylib PATHS "${LLVM_LIBRARY_DIRS}/clang/${LLVM_MAJOR_VERSION}/lib/darwin")
find_file(RT_UBSAN_DYNAMIC NAMES libclang_rt.ubsan_osx_dynamic.dylib PATHS "${LLVM_LIBRARY_DIRS}/clang/${LLVM_MAJOR_VERSION}/lib/darwin")
find_file(RT_LSAN_DYNAMIC NAMES libclang_rt.lsan_osx_dynamic.dylib PATHS "${LLVM_LIBRARY_DIRS}/clang/${LLVM_MAJOR_VERSION}/lib/darwin")
set(sanitizer_runtime_libraries
${RT_ASAN_DYNAMIC}
${RT_TSAN_DYNAMIC}
# Unused
# ${RT_UBSAN_DYNAMIC}
# ${RT_LSAN_DYNAMIC}
)
endif()
message(STATUS "linking to llvm libs ${lld_libs}")
message(STATUS "Found lld libs ${lld_libs}")
endif()
message(STATUS "linking to llvm libs ${lld_libs}")
message(STATUS "Found lld libs ${lld_libs}")
add_library(c3c_wrappers STATIC wrapper/src/wrapper.cpp)
add_library(miniz STATIC dependencies/miniz/miniz.c)
add_executable(c3c
@@ -279,7 +284,6 @@ add_executable(c3c
src/compiler/json_output.c
src/compiler/lexer.c
src/compiler/linker.c
src/compiler/llvm_codegen.c
src/compiler/abi/c_abi_aarch64.c
src/compiler/abi/c_abi.c
src/compiler/abi/c_abi_riscv.c
@@ -287,14 +291,6 @@ add_executable(c3c
src/compiler/abi/c_abi_win64.c
src/compiler/abi/c_abi_x64.c
src/compiler/abi/c_abi_x86.c
src/compiler/llvm_codegen_debug_info.c
src/compiler/llvm_codegen_expr.c
src/compiler/llvm_codegen_function.c
src/compiler/llvm_codegen_instr.c
src/compiler/llvm_codegen_module.c
src/compiler/llvm_codegen_stmt.c
src/compiler/llvm_codegen_type.c
src/compiler/llvm_codegen_value.c
src/compiler/module.c
src/compiler/number.c
src/compiler/parse_expr.c
@@ -337,12 +333,10 @@ add_executable(c3c
src/utils/cpus.c
src/utils/unzipper.c
src/compiler/decltable.c
src/compiler/mac_support.c
src/compiler/llvm_codegen_storeload.c
src/compiler/mac_support.c
src/compiler/windows_support.c
src/compiler/codegen_asm.c
src/compiler/asm_target.c
src/compiler/llvm_codegen_builtins.c
src/compiler/asm_target.c
src/compiler/expr.c
src/utils/time.c
src/utils/http.c
@@ -365,6 +359,36 @@ else()
COMMAND ${CMAKE_COMMAND} -P "${CMAKE_CURRENT_LIST_DIR}/git_hash.cmake")
endif()
if(C3_WITH_LLVM)
target_sources(c3c PRIVATE
src/compiler/llvm_codegen.c
src/compiler/llvm_codegen_debug_info.c
src/compiler/llvm_codegen_expr.c
src/compiler/llvm_codegen_function.c
src/compiler/llvm_codegen_instr.c
src/compiler/llvm_codegen_module.c
src/compiler/llvm_codegen_stmt.c
src/compiler/llvm_codegen_type.c
src/compiler/llvm_codegen_value.c
src/compiler/llvm_codegen_storeload.c
src/compiler/llvm_codegen_builtins.c)
target_compile_definitions(c3c PUBLIC LLVM_AVAILABLE=1)
add_library(c3c_wrappers STATIC wrapper/src/wrapper.cpp)
else()
target_sources(c3c PRIVATE src/utils/hostinfo.c)
target_compile_definitions(c3c PUBLIC LLVM_AVAILABLE=0)
endif()
target_include_directories(c3c PRIVATE
"${CMAKE_SOURCE_DIR}/src/"
"${CMAKE_BINARY_DIR}")
target_include_directories(miniz PUBLIC
"${CMAKE_SOURCE_DIR}/dependencies/miniz/")
if (C3_USE_TB)
file(GLOB tilde-sources
tilde-backend/src/tb/*.c
@@ -397,25 +421,29 @@ if (C3_USE_TB)
target_include_directories(c3c PRIVATE
"${CMAKE_SOURCE_DIR}/tilde-backend/include/")
else()
target_compile_definitions(c3c PUBLIC TB_AVAILABLE=0)
endif()
if(C3_WITH_LLVM)
target_link_libraries(c3c ${llvm_libs} miniz c3c_wrappers ${lld_libs})
target_include_directories(c3c PRIVATE
"${CMAKE_SOURCE_DIR}/src/"
"${CMAKE_SOURCE_DIR}/wrapper/include/"
"${CMAKE_BINARY_DIR}")
target_include_directories(c3c PRIVATE
"${CMAKE_SOURCE_DIR}/wrapper/include/")
target_include_directories(c3c_wrappers PRIVATE
"${CMAKE_SOURCE_DIR}/wrapper/include/")
target_include_directories(c3c_wrappers PRIVATE
"${CMAKE_SOURCE_DIR}/wrapper/include/")
target_link_libraries(c3c_wrappers ${llvm_libs} ${lld_libs})
target_include_directories(miniz PUBLIC
"${CMAKE_SOURCE_DIR}/dependencies/miniz/")
else()
target_link_libraries(c3c_wrappers ${llvm_libs} ${lld_libs})
target_link_libraries(c3c ${llvm_libs} miniz c3c_wrappers ${lld_libs})
target_link_libraries(c3c ${llvm_libs} miniz ${lld_libs})
endif()
if(C3_USE_MIMALLOC)
target_link_libraries(c3c mimalloc-static)
@@ -442,36 +470,44 @@ endif()
if(MSVC)
message("Adding MSVC options")
target_compile_options(c3c PRIVATE /wd4068 /wd4090 /WX /Wv:18)
target_compile_options(c3c_wrappers PUBLIC /wd4624 /wd4267 /wd4244 /WX /Wv:18)
if (NOT LLVM_ENABLE_RTTI)
target_compile_options(c3c_wrappers PUBLIC /GR-)
if(C3_WITH_LLVM)
target_compile_options(c3c_wrappers PUBLIC /wd4624 /wd4267 /wd4244 /WX /Wv:18)
if(NOT LLVM_ENABLE_RTTI)
target_compile_options(c3c_wrappers PUBLIC /GR-)
endif()
target_link_options(c3c_wrappers PUBLIC /ignore:4099)
endif()
target_link_options(c3c_wrappers PUBLIC /ignore:4099)
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
target_compile_options(c3c PUBLIC /MTd)
target_compile_options(c3c_wrappers PUBLIC /MTd)
if (C3_WITH_LLVM)
target_compile_options(c3c_wrappers PUBLIC /MTd)
endif()
target_compile_options(miniz PUBLIC /MTd)
if (C3_USE_TB)
target_compile_options(tilde-backend PUBLIC /MTd)
endif()
else()
target_compile_options(c3c PUBLIC /MT)
target_compile_options(c3c_wrappers PUBLIC /MT)
if (C3_WITH_LLVM)
target_compile_options(c3c_wrappers PUBLIC /MT)
endif()
target_compile_options(miniz PUBLIC /MT)
if (C3_USE_TB)
target_compile_options(tilde-backend PUBLIC /MT)
endif()
endif()
set(clang_lib_dir ${llvm_dir}/lib/clang/${C3_LLVM_VERSION}/lib/windows)
set(sanitizer_runtime_libraries
${clang_lib_dir}/clang_rt.asan-x86_64.lib
${clang_lib_dir}/clang_rt.asan_dynamic-x86_64.lib
${clang_lib_dir}/clang_rt.asan_dynamic-x86_64.dll
${clang_lib_dir}/clang_rt.asan_dynamic_runtime_thunk-x86_64.lib)
if(C3_WITH_LLVM)
set(clang_lib_dir ${llvm_dir}/lib/clang/${C3_LLVM_VERSION}/lib/windows)
set(sanitizer_runtime_libraries
${clang_lib_dir}/clang_rt.asan-x86_64.lib
${clang_lib_dir}/clang_rt.asan_dynamic-x86_64.lib
${clang_lib_dir}/clang_rt.asan_dynamic-x86_64.dll
${clang_lib_dir}/clang_rt.asan_dynamic_runtime_thunk-x86_64.lib)
endif()
else()
message(STATUS "using gcc/clang warning switches")
target_link_options(c3c PRIVATE -pthread)
if (NOT LLVM_ENABLE_RTTI)
if (C3_WITH_LLVM AND NOT LLVM_ENABLE_RTTI)
target_compile_options(c3c_wrappers PRIVATE -fno-rtti)
endif()
target_compile_options(c3c PRIVATE -pthread -Wall -Werror -Wno-unknown-pragmas -Wno-unused-result
@@ -481,7 +517,7 @@ endif()
install(TARGETS c3c DESTINATION bin)
install(DIRECTORY lib/ DESTINATION lib/c3)
if (DEFINED sanitizer_runtime_libraries)
if (C3_WITH_LLVM AND DEFINED sanitizer_runtime_libraries)
add_custom_command(TARGET c3c POST_BUILD
COMMAND "${CMAKE_COMMAND}" -E rm -rf -- $<TARGET_FILE_DIR:c3c>/c3c_rt
COMMAND "${CMAKE_COMMAND}" -E make_directory $<TARGET_FILE_DIR:c3c>/c3c_rt

View File

@@ -484,8 +484,22 @@ static void print_version(void)
#endif
PRINTF("Installed directory: %s", find_executable_path());
PRINTF("Git Hash: %s", GIT_HASH);
#if LLVM_AVAILABLE && TB_AVAILABLE
PRINTF("Backends: LLVM; TB");
#elif LLVM_AVAILABLE
PRINTF("Backends: LLVM");
#elif TB_AVAILABLE
PRINTF("Backends: TB");
#else
PRINTF("No backends available");
#endif
#if LLVM_AVAILABLE
PRINTF("LLVM version: %s", llvm_version);
PRINTF("LLVM default target: %s", llvm_target);
#endif
}
static void add_linker_arg(BuildOptions *options, const char *arg)

View File

@@ -7,8 +7,10 @@
#include "../utils/whereami.h"
#if PLATFORM_POSIX
#include <sys/wait.h>
#endif
#endif
#if LLVM_AVAILABLE
#include "c3_llvm.h"
#endif
#include <errno.h>
#define MAX_OUTPUT_FILES 1000000
@@ -111,11 +113,18 @@ typedef struct CompileData_
Task task;
} CompileData;
#if LLVM_AVAILABLE
void thread_compile_task_llvm(void *compile_data)
{
CompileData *data = compile_data;
data->object_name = llvm_codegen(data->context);
}
#else
void thread_compile_task_llvm(void *compile_data)
{
error_exit("LLVM backend not available.");
}
#endif
void thread_compile_task_tb(void *compile_data)
{
@@ -451,9 +460,13 @@ void compiler_compile(void)
switch (compiler.build.backend)
{
case BACKEND_LLVM:
#if LLVM_AVAILABLE
gen_contexts = llvm_gen(modules, module_count);
task = &thread_compile_task_llvm;
break;
#else
error_exit("C3C compiled without LLVM!");
#endif
break;
case BACKEND_TB:
gen_contexts = tilde_gen(modules, module_count);
task = &thread_compile_task_tb;
@@ -1242,8 +1255,14 @@ void compile()
setup_bool_define("COMPILER_SAFE_MODE", safe_mode_enabled());
setup_bool_define("DEBUG_SYMBOLS", compiler.build.debug_info == DEBUG_INFO_FULL);
setup_bool_define("BACKTRACE", compiler.build.show_backtrace != SHOW_BACKTRACE_OFF);
setup_int_define("LLVM_VERSION", llvm_version_major, type_int);
setup_bool_define("BENCHMARKING", compiler.build.benchmarking);
#if LLVM_AVAILABLE
setup_int_define("LLVM_VERSION", llvm_version_major, type_int);
#else
setup_int_define("LLVM_VERSION", 0, type_int);
#endif
setup_bool_define("BENCHMARKING", compiler.build.benchmarking);
setup_int_define("JMP_BUF_SIZE", jump_buffer_size(), type_int);
setup_bool_define("TESTING", compiler.build.testing);
setup_bool_define("ADDRESS_SANITIZER", compiler.build.feature.sanitize_address);

View File

@@ -1,6 +1,8 @@
#include "compiler_internal.h"
#include "../utils/whereami.h"
#if LLVM_AVAILABLE
#include "c3_llvm.h"
#endif
#if PLATFORM_POSIX
#include <glob.h>
@@ -714,6 +716,7 @@ static bool link_exe(const char *output_file, const char **files_to_link, unsign
// This isn't used in most cases, but its contents should get freed after linking.
bool success;
#if LLVM_AVAILABLE
unsigned count = assemble_link_arguments(args, vec_size(args));
switch (compiler.platform.object_format)
{
@@ -732,6 +735,10 @@ static bool link_exe(const char *output_file, const char **files_to_link, unsign
default:
UNREACHABLE
}
#else
success = false;
error = "linking (.exe) is not implemented for C3C compiled without LLVM";
#endif
if (!success)
{
error_exit("Failed to create an executable: %s", error);
@@ -960,8 +967,9 @@ bool dynamic_lib_linker(const char *output_file, const char **files, unsigned fi
return true;
}
bool success;
const char *error = NULL;
unsigned count = assemble_link_arguments(args, vec_size(args));
const char *error = NULL;
#if LLVM_AVAILABLE
unsigned count = assemble_link_arguments(args, vec_size(args));
switch (compiler.platform.object_format)
{
case OBJ_FORMAT_COFF:
@@ -979,6 +987,10 @@ bool dynamic_lib_linker(const char *output_file, const char **files, unsigned fi
default:
UNREACHABLE
}
#else
success = false;
error = "linking not implemented for c3c compiled without llvm";
#endif
if (!success)
{
error_exit("Failed to create a dynamic library: %s", error);
@@ -989,6 +1001,7 @@ bool dynamic_lib_linker(const char *output_file, const char **files, unsigned fi
bool static_lib_linker(const char *output_file, const char **files, unsigned file_count)
{
#if LLVM_AVAILABLE
ArFormat format;
switch (compiler.platform.os)
{
@@ -1009,6 +1022,9 @@ bool static_lib_linker(const char *output_file, const char **files, unsigned fil
break;
}
return llvm_ar(output_file, files, file_count, format);
#else
return false;
#endif
}
bool linker(const char *output_file, const char **files, unsigned file_count)

View File

@@ -1,8 +1,14 @@
#if LLVM_AVAILABLE
#include <llvm-c/Target.h>
#include <llvm-c/TargetMachine.h>
#include <llvm-c/Core.h>
#endif
#include "compiler_internal.h"
#if LLVM_AVAILABLE
#include "c3_llvm.h"
#else
#include "utils/hostinfo.h"
#endif
static bool x64features_contains(X86Features *cpu_features, X86Feature feature);
static ObjectFormatType object_format_from_os(OsType os, ArchType arch_type);
@@ -782,17 +788,24 @@ static const char *x86_cpu_from_set(X86CpuSet set)
case X86CPU_AVX512:
return "x86-64-v4";
case X86CPU_NATIVE:
#if LLVM_AVAILABLE
return LLVMGetHostCPUName();
}
#else
return hostinfo_x86_cpu_name();
#endif
}
UNREACHABLE
}
static void x86_features_from_host(X86Features *cpu_features)
{
#if LLVM_AVAILABLE
char *features = LLVMGetHostCPUFeatures();
INFO_LOG("Detected the following host features: %s", features);
INFO_LOG("For %s", LLVMGetHostCPUName());
char *tok = strtok(features, ",");
INFO_LOG("For %s",
LLVMGetHostCPUName());
char *tok = strtok(features, ",");
*cpu_features = x86_feature_zero;
while (tok != NULL)
{
@@ -822,6 +835,9 @@ static void x86_features_from_host(X86Features *cpu_features)
tok = strtok(NULL, ",");
}
LLVMDisposeMessage(features);
#else
hostinfo_x86_features(cpu_features);
#endif
}
static void x86features_from_cpu(X86Features *cpu_features, X86CpuSet cpu_set)
@@ -1530,7 +1546,7 @@ static AlignData os_target_alignment_of_int(OsType os, ArchType arch, uint32_t b
case ARCH_TYPE_XTENSA:
return (AlignData) { MIN(64u, bits), MIN(64u, bits) };
case ARCH_TYPE_X86_64:
#if LLVM_VERSION_MAJOR < 18
#if !LLVM_AVAILABLE || LLVM_VERSION_MAJOR < 18
return (AlignData) { MIN(64u, bits), MIN(64u, bits) };
#else
FALLTHROUGH;
@@ -1543,7 +1559,7 @@ static AlignData os_target_alignment_of_int(OsType os, ArchType arch, uint32_t b
return (AlignData) { bits, bits };
case ARCH_TYPE_X86:
if (bits <= 32) return (AlignData) { bits, bits };
#if LLVM_VERSION_MAJOR > 17
#if !LLVM_AVAILABLE || LLVM_VERSION_MAJOR > 17
if (bits == 128) return (AlignData) { 128, 128 };
#endif
if (os == OS_TYPE_ELFIAMCU) return (AlignData) { 32, 32 };
@@ -1718,19 +1734,6 @@ static bool arch_os_pic_default_forced(ArchType arch, OsType os)
UNREACHABLE
}
#define INITIALIZE_TARGET(X) do { \
DEBUG_LOG("Initialize target: %s.", #X); \
LLVMInitialize ## X ## AsmParser(); \
LLVMInitialize ## X ## AsmPrinter(); \
LLVMInitialize ## X ## TargetInfo(); \
LLVMInitialize ## X ## Target(); \
LLVMInitialize ## X ## Disassembler(); \
LLVMInitialize ## X ## TargetMC(); \
} while(0)
INLINE const char *llvm_macos_target_triple(const char *triple)
{
if (compiler.build.macos.min_version)
@@ -1755,6 +1758,17 @@ INLINE const char *llvm_macos_target_triple(const char *triple)
return scratch_buffer_to_string();
}
#if LLVM_AVAILABLE
#define INITIALIZE_TARGET(X) do { \
DEBUG_LOG("Initialize target: %s.", #X); \
LLVMInitialize ## X ## AsmParser(); \
LLVMInitialize ## X ## AsmPrinter(); \
LLVMInitialize ## X ## TargetInfo(); \
LLVMInitialize ## X ## Target(); \
LLVMInitialize ## X ## Disassembler(); \
LLVMInitialize ## X ## TargetMC(); \
} while(0)
#if LLVM_VERSION_MAJOR > 19
#define XTENSA_AVAILABLE 1
#else
@@ -1815,7 +1829,11 @@ void *llvm_target_machine_create(void)
return result;
}
#else
#define XTENSA_AVAILABLE 1
#endif
void target_setup(BuildTarget *target)
@@ -1843,6 +1861,7 @@ void target_setup(BuildTarget *target)
compiler.platform.alloca_address_space = 0;
#if LLVM_AVAILABLE
// Create a specific target machine
LLVMCodeGenOptLevel level;
@@ -1867,8 +1886,15 @@ void target_setup(BuildTarget *target)
}
compiler.platform.llvm_opt_level = (int)level;
#endif
INFO_LOG("Triple picked was %s.", compiler.platform.target_triple);
INFO_LOG("Default was %s.", LLVM_DEFAULT_TARGET_TRIPLE);
#if LLVM_AVAILABLE
INFO_LOG("Default was %s.", LLVM_DEFAULT_TARGET_TRIPLE);
#else
INFO_LOG("Default was %s.", hostinfo_default_triple());
#endif
StringSlice target_triple_string = slice_from_string(compiler.platform.target_triple);
compiler.platform.arch = arch_from_llvm_string(slice_next_token(&target_triple_string, '-'));

View File

@@ -65,7 +65,9 @@ typedef struct
typedef struct
{
const char *target_triple;
int llvm_opt_level;
#if LLVM_AVAILABLE
int llvm_opt_level;
#endif
const char *cpu;
const char *features;
ArchType arch;

121
src/utils/hostinfo.c Normal file
View File

@@ -0,0 +1,121 @@
#include "../compiler/compiler_internal.h"
#include "hostinfo.h"
#include <stdlib.h>
static int is_le(void) {
unsigned int i = 1;
char *c;
c = (char *) &i;
return (*c == 1);
}
ArchType hostinfo_arch_type(void) {
#if defined(__x86_64__) || defined(_M_X64)
return ARCH_TYPE_X86_64;
#elif defined(i386) || defined(__i386__) || defined(__i386) || defined(_M_IX86)
return ARCH_TYPE_X86;
#elif (defined(__arm__) && !defined(__thumb__)) || (defined(__TARGET_ARCH_ARM) && !defined(__TARGET_ARCH_THUMB)) || defined(__ARM) || defined(_M_ARM) || defined(_M_ARM_T) || defined(__ARM_ARCH)
return is_le() ? ARCH_TYPE_ARM : ARCH_TYPE_ARMB;
#elif defined(__thumb__) || defined(__TARGET_ARCH_THUMB) || defined(__ARM) || defined(_M_ARM) || defined(_M_ARM_T) || defined(__ARM_ARCH)
return is_le() ? ARCH_TYPE_THUMB : ARCH_TYPE_THUMBEB;
#elif defined(__aarch64__) || defined(_M_ARM64)
return is_le() ? ARCH_TYPE_AARCH64 : ARCH_TYPE_AARCH64_BE;
#elif defined(mips) || defined(__mips__) || defined(__mips)
return ARCH_UNSUPPORTED;
#elif defined(__sh__)
return ARCH_UNSUPPORTED;
#elif defined(__riscv) && defined(__riscv32)
return ARCH_TYPE_RISCV32;
#elif defined(__riscv) && defined(__riscv64)
return ARCH_TYPE_RISCV64;
#elif defined(__PPC64__) || defined(__ppc64__) || defined(_ARCH_PPC64) || defined(__powerpc64__)
return is_le() ? ARCH_TYPE_PPC64LE : ARCH_TYPE_PPC64;
#elif defined(__powerpc) || defined(__powerpc__) || defined(__POWERPC__) || defined(__ppc__) || defined(__PPC__) || defined(_ARCH_PPC)
return ARCH_TYPE_PPC;
#elif defined(__sparc__) || defined(__sparc)
return ARCH_UNSUPPORTED
#else
return ARCH_UNSUPPORTED
#endif
}
static const char * llvm_arch_name(ArchType ty) {
switch (ty) {
case ARCH_TYPE_X86_64: return "x86_64";
case ARCH_TYPE_X86: return "x86";
case ARCH_TYPE_ARM: return "arm";
case ARCH_TYPE_ARMB: return "armbe";
case ARCH_TYPE_AARCH64: return "aarch64";
case ARCH_TYPE_AARCH64_BE: return "aarch64be";
case ARCH_TYPE_THUMB: return "thumb";
case ARCH_TYPE_THUMBEB: return "thumbeb";
case ARCH_TYPE_WASM64: return "wasm64";
case ARCH_TYPE_WASM32: return "wasm32";
case ARCH_TYPE_XTENSA: return "xtensa";
case ARCH_TYPE_PPC: return "ppc";
case ARCH_TYPE_PPC64: return "ppc64";
case ARCH_TYPE_PPC64LE: return "ppc64le";
case ARCH_TYPE_RISCV32: return "riscv32";
case ARCH_TYPE_RISCV64: return "riscv64";
default:
case ARCH_TYPE_UNKNOWN: return "unknown";
}
}
void hostinfo_x86_features(X86Features *cpu_features) {
#if defined(__x86_64__) || defined(_M_X64)
// TODO
#endif
}
EnvironmentType hostinfo_env_type(void) {
return ENV_TYPE_UNKNOWN;
}
OsType hostinfo_os_type(void) {
if (system("freebsd-version -k") == 0) {
return OS_TYPE_FREE_BSD;
}
if (system("uname -r") == 0) {
return OS_TYPE_LINUX;
}
if (system("cd C:/Windows") == 0) {
return OS_TYPE_WIN32;
}
return OS_TYPE_UNKNOWN;
}
static const char * llvm_os_name(OsType os) {
switch (os) {
case OS_TYPE_FREE_BSD: return "frebsd";
case OS_TYPE_LINUX: return "linux";
case OS_TYPE_WIN32: return "win32";
default: return "unknown";
}
}
VendorType hostinfo_vendor_type(void) {
return VENDOR_UNKNOWN;
}
static char triple[128];
static int triple_init = 0;
const char * hostinfo_default_triple(void) {
if (!triple_init) {
sprintf(triple, "%s-unknown-unknown-%s",
llvm_arch_name(hostinfo_arch_type()),
llvm_os_name(hostinfo_os_type()));
triple_init = 1;
}
return triple;
}
const char * hostinfo_x86_cpu_name(void) {
return "x86";
}

12
src/utils/hostinfo.h Normal file
View File

@@ -0,0 +1,12 @@
#if !defined(HOSTINFO_H) && !LLVM_AVAILABLE
#define HOSTINFO_H
void hostinfo_x86_features(X86Features *cpu_features);
ArchType hostinfo_arch_type(void);
EnvironmentType hostinfo_env_type(void);
OsType hostinfo_os_type(void);
VendorType hostinfo_vendor_type(void);
const char * hostinfo_default_triple(void);
const char * hostinfo_x86_cpu_name(void); // for example: "x86-64", "x86-64-v4"
#endif