mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
ability to disable llvm at compile time (#1433)
ability to disable llvm at compile time
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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, '-'));
|
||||
|
||||
@@ -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
121
src/utils/hostinfo.c
Normal 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
12
src/utils/hostinfo.h
Normal 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
|
||||
Reference in New Issue
Block a user