Use C API for creating target machine
All checks were successful
All checks were successful
This commit is contained in:
parent
b5f92727b4
commit
a74121567a
@ -579,6 +579,13 @@ target_get_native = fn () Target
|
||||
return { .cpu = .x86_64, .os = .linux };
|
||||
}
|
||||
|
||||
target_compare = fn (a: Target, b: Target) u1
|
||||
{
|
||||
>is_same_cpu = a.cpu == b.cpu;
|
||||
>is_same_os = a.cpu == b.cpu;
|
||||
return is_same_cpu and is_same_os;
|
||||
}
|
||||
|
||||
CompileOptions = struct
|
||||
{
|
||||
content: []u8,
|
||||
@ -843,7 +850,7 @@ LLVMIntrinsicIndex = enum
|
||||
[extern] llvm_host_cpu_name = fn [cc(c)] () []u8;
|
||||
[extern] llvm_host_cpu_features = fn [cc(c)] () []u8;
|
||||
|
||||
host_triple: []u8 = zero;
|
||||
host_target_triple: []u8 = zero;
|
||||
host_cpu_model: []u8 = zero;
|
||||
host_cpu_features: []u8 = zero;
|
||||
|
||||
@ -860,7 +867,7 @@ llvm_initialize_targets = fn () void
|
||||
LLVMInitializeX86AsmParser();
|
||||
LLVMInitializeX86Disassembler();
|
||||
|
||||
host_triple = llvm_default_target_triple();
|
||||
host_target_triple = llvm_default_target_triple();
|
||||
host_cpu_model = llvm_host_cpu_name();
|
||||
host_cpu_features = llvm_host_cpu_features();
|
||||
|
||||
@ -868,7 +875,17 @@ llvm_initialize_targets = fn () void
|
||||
}
|
||||
}
|
||||
|
||||
LLVMCodeGenerationOptimizationLevel = enum
|
||||
{
|
||||
none = 0,
|
||||
less = 1,
|
||||
default = 2,
|
||||
aggressive = 3,
|
||||
}
|
||||
|
||||
[extern] LLVMContextCreate = fn [cc(c)] () &LLVMContext;
|
||||
[extern] llvm_context_create_module = fn (context: &LLVMContext, name: []u8) &LLVMModule;
|
||||
[extern] LLVMCreateBuilderInContext = fn (context: &LLVMContext) &LLVMBuilder;
|
||||
|
||||
ModuleLLVM = struct
|
||||
{
|
||||
@ -2650,8 +2667,37 @@ parse = fn (module: &Module) void
|
||||
|
||||
emit = fn (module: &Module) void
|
||||
{
|
||||
assert(!module.current_function);
|
||||
assert(!module.current_macro_instantiation);
|
||||
assert(!module.current_macro_declaration);
|
||||
llvm_initialize_targets();
|
||||
>context = LLVMContextCreate();
|
||||
>m = llvm_context_create_module(context, module.name);
|
||||
>builder = LLVMCreateBuilderInContext(context);
|
||||
|
||||
>target_triple: []u8 = undefined;
|
||||
>cpu_model: []u8 = undefined;
|
||||
>cpu_features: []u8 = undefined;
|
||||
|
||||
if (target_compare(module.target, target_get_native()))
|
||||
{
|
||||
target_triple = host_target_triple;
|
||||
cpu_model = host_cpu_model;
|
||||
cpu_features = host_cpu_features;
|
||||
}
|
||||
else
|
||||
{
|
||||
#trap();
|
||||
}
|
||||
|
||||
>code_generation_optimization_level: LLVMCodeGenerationOptimizationLevel = undefined;
|
||||
switch (module.build_mode)
|
||||
{
|
||||
.debug_none, .debug => { code_generation_optimization_level = .none; },
|
||||
.soft_optimize => { code_generation_optimization_level = .less; },
|
||||
.optimize_for_speed, .optimize_for_size => { code_generation_optimization_level = .default; },
|
||||
.aggressively_optimize_for_speed, .aggressively_optimize_for_size => { code_generation_optimization_level = .aggressive; },
|
||||
}
|
||||
}
|
||||
|
||||
compile = fn (arena: &Arena, options: CompileOptions) void
|
||||
|
@ -249,6 +249,22 @@ struct Target
|
||||
OperatingSystem os;
|
||||
};
|
||||
|
||||
fn Target target_get_native()
|
||||
{
|
||||
return {
|
||||
.cpu = CPUArchitecture::x86_64,
|
||||
.os = OperatingSystem::linux_,
|
||||
};
|
||||
}
|
||||
|
||||
fn bool target_compare(Target a, Target b)
|
||||
{
|
||||
auto is_same_cpu = a.cpu == b.cpu;
|
||||
auto is_same_os = a.os == b.os;
|
||||
|
||||
return is_same_cpu && is_same_os;
|
||||
}
|
||||
|
||||
struct Compile
|
||||
{
|
||||
String relative_file_path;
|
||||
|
@ -349,41 +349,7 @@ fn void llvm_initialize(Module* module)
|
||||
auto context = LLVMContextCreate();
|
||||
auto m = llvm_context_create_module(context, module->name);
|
||||
auto builder = LLVMCreateBuilderInContext(context);
|
||||
BBLLVMCodeGenerationOptimizationLevel code_generation_optimization_level;
|
||||
switch (module->build_mode)
|
||||
{
|
||||
case BuildMode::debug_none:
|
||||
case BuildMode::debug:
|
||||
code_generation_optimization_level = BBLLVMCodeGenerationOptimizationLevel::none;
|
||||
break;
|
||||
case BuildMode::soft_optimize:
|
||||
code_generation_optimization_level = BBLLVMCodeGenerationOptimizationLevel::less;
|
||||
break;
|
||||
case BuildMode::optimize_for_speed:
|
||||
case BuildMode::optimize_for_size:
|
||||
code_generation_optimization_level = BBLLVMCodeGenerationOptimizationLevel::normal;
|
||||
break;
|
||||
case BuildMode::aggressively_optimize_for_speed:
|
||||
case BuildMode::aggressively_optimize_for_size:
|
||||
code_generation_optimization_level = BBLLVMCodeGenerationOptimizationLevel::aggressive;
|
||||
break;
|
||||
case BuildMode::count:
|
||||
unreachable();
|
||||
}
|
||||
auto triple = llvm_default_target_triple();
|
||||
BBLLVMTargetMachineCreate target_machine_options = {
|
||||
.target_triple = triple,
|
||||
.cpu_model = llvm_host_cpu_name(),
|
||||
.cpu_features = llvm_host_cpu_features(),
|
||||
.relocation_model = BBLLVMRelocationModel::default_relocation,
|
||||
.code_model = BBLLVMCodeModel::none,
|
||||
.optimization_level = code_generation_optimization_level,
|
||||
};
|
||||
String error_message = {};
|
||||
auto target_machine = llvm_create_target_machine(&target_machine_options, &error_message);
|
||||
auto target_data = LLVMCreateTargetDataLayout(target_machine);
|
||||
LLVMSetModuleDataLayout(m, target_data);
|
||||
LLVMSetTarget(m, (char*)triple.pointer);
|
||||
|
||||
LLVMDIBuilderRef di_builder = 0;
|
||||
LLVMMetadataRef di_compile_unit = 0;
|
||||
LLVMMetadataRef di_file = 0;
|
||||
@ -410,6 +376,64 @@ fn void llvm_initialize(Module* module)
|
||||
module->scope.llvm = di_compile_unit;
|
||||
}
|
||||
|
||||
String target_triple = {};
|
||||
String cpu_model = {};
|
||||
String cpu_features = {};
|
||||
|
||||
if (target_compare(module->target, target_get_native()))
|
||||
{
|
||||
target_triple = llvm_global.host_triple;
|
||||
cpu_model = llvm_global.host_cpu_model;
|
||||
cpu_features = llvm_global.host_cpu_features;
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO
|
||||
report_error();
|
||||
}
|
||||
|
||||
auto target_machine_options = LLVMCreateTargetMachineOptions();
|
||||
LLVMTargetMachineOptionsSetCPU(target_machine_options, (char*)cpu_model.pointer);
|
||||
LLVMTargetMachineOptionsSetFeatures(target_machine_options, (char*)cpu_features.pointer);
|
||||
|
||||
LLVMCodeGenOptLevel code_generation_optimization_level;
|
||||
switch (module->build_mode)
|
||||
{
|
||||
case BuildMode::debug_none:
|
||||
case BuildMode::debug:
|
||||
code_generation_optimization_level = LLVMCodeGenLevelNone;
|
||||
break;
|
||||
case BuildMode::soft_optimize:
|
||||
code_generation_optimization_level = LLVMCodeGenLevelLess;
|
||||
break;
|
||||
case BuildMode::optimize_for_speed:
|
||||
case BuildMode::optimize_for_size:
|
||||
code_generation_optimization_level = LLVMCodeGenLevelDefault;
|
||||
break;
|
||||
case BuildMode::aggressively_optimize_for_speed:
|
||||
case BuildMode::aggressively_optimize_for_size:
|
||||
code_generation_optimization_level = LLVMCodeGenLevelAggressive;
|
||||
break;
|
||||
case BuildMode::count:
|
||||
unreachable();
|
||||
}
|
||||
LLVMTargetMachineOptionsSetCodeGenOptLevel(target_machine_options, code_generation_optimization_level);
|
||||
|
||||
LLVMTargetRef target = 0;
|
||||
char* error_message = 0;
|
||||
auto result = LLVMGetTargetFromTriple((char*)target_triple.pointer, &target, &error_message);
|
||||
if (result != 0)
|
||||
{
|
||||
report_error();
|
||||
}
|
||||
assert(!error_message);
|
||||
|
||||
auto target_machine = LLVMCreateTargetMachineWithOptions(target, (char*)target_triple.pointer, target_machine_options);
|
||||
|
||||
auto target_data = LLVMCreateTargetDataLayout(target_machine);
|
||||
LLVMSetModuleDataLayout(m, target_data);
|
||||
LLVMSetTarget(m, (char*)target_triple.pointer);
|
||||
|
||||
module->llvm = {
|
||||
.context = context,
|
||||
.module = m,
|
||||
|
Loading…
x
Reference in New Issue
Block a user