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 };
|
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
|
CompileOptions = struct
|
||||||
{
|
{
|
||||||
content: []u8,
|
content: []u8,
|
||||||
@ -843,7 +850,7 @@ LLVMIntrinsicIndex = enum
|
|||||||
[extern] llvm_host_cpu_name = fn [cc(c)] () []u8;
|
[extern] llvm_host_cpu_name = fn [cc(c)] () []u8;
|
||||||
[extern] llvm_host_cpu_features = 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_model: []u8 = zero;
|
||||||
host_cpu_features: []u8 = zero;
|
host_cpu_features: []u8 = zero;
|
||||||
|
|
||||||
@ -860,7 +867,7 @@ llvm_initialize_targets = fn () void
|
|||||||
LLVMInitializeX86AsmParser();
|
LLVMInitializeX86AsmParser();
|
||||||
LLVMInitializeX86Disassembler();
|
LLVMInitializeX86Disassembler();
|
||||||
|
|
||||||
host_triple = llvm_default_target_triple();
|
host_target_triple = llvm_default_target_triple();
|
||||||
host_cpu_model = llvm_host_cpu_name();
|
host_cpu_model = llvm_host_cpu_name();
|
||||||
host_cpu_features = llvm_host_cpu_features();
|
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] LLVMContextCreate = fn [cc(c)] () &LLVMContext;
|
||||||
|
[extern] llvm_context_create_module = fn (context: &LLVMContext, name: []u8) &LLVMModule;
|
||||||
|
[extern] LLVMCreateBuilderInContext = fn (context: &LLVMContext) &LLVMBuilder;
|
||||||
|
|
||||||
ModuleLLVM = struct
|
ModuleLLVM = struct
|
||||||
{
|
{
|
||||||
@ -2650,8 +2667,37 @@ parse = fn (module: &Module) void
|
|||||||
|
|
||||||
emit = 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();
|
llvm_initialize_targets();
|
||||||
>context = LLVMContextCreate();
|
>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
|
compile = fn (arena: &Arena, options: CompileOptions) void
|
||||||
|
@ -249,6 +249,22 @@ struct Target
|
|||||||
OperatingSystem os;
|
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
|
struct Compile
|
||||||
{
|
{
|
||||||
String relative_file_path;
|
String relative_file_path;
|
||||||
|
@ -349,41 +349,7 @@ fn void llvm_initialize(Module* module)
|
|||||||
auto context = LLVMContextCreate();
|
auto context = LLVMContextCreate();
|
||||||
auto m = llvm_context_create_module(context, module->name);
|
auto m = llvm_context_create_module(context, module->name);
|
||||||
auto builder = LLVMCreateBuilderInContext(context);
|
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;
|
LLVMDIBuilderRef di_builder = 0;
|
||||||
LLVMMetadataRef di_compile_unit = 0;
|
LLVMMetadataRef di_compile_unit = 0;
|
||||||
LLVMMetadataRef di_file = 0;
|
LLVMMetadataRef di_file = 0;
|
||||||
@ -410,6 +376,64 @@ fn void llvm_initialize(Module* module)
|
|||||||
module->scope.llvm = di_compile_unit;
|
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 = {
|
module->llvm = {
|
||||||
.context = context,
|
.context = context,
|
||||||
.module = m,
|
.module = m,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user