forked from M-Labs/nac3
core: Add CodeGenTargetMachineOptions
Needed in a future commit.
This commit is contained in:
parent
eb63f2ad48
commit
2482a1ef9b
|
@ -12,7 +12,7 @@ use inkwell::{
|
||||||
targets::*,
|
targets::*,
|
||||||
OptimizationLevel,
|
OptimizationLevel,
|
||||||
};
|
};
|
||||||
use nac3core::codegen::{CodeGenLLVMOptions, gen_func_impl};
|
use nac3core::codegen::{CodeGenLLVMOptions, CodeGenTargetMachineOptions, gen_func_impl};
|
||||||
use nac3core::toplevel::builtins::get_exn_constructor;
|
use nac3core::toplevel::builtins::get_exn_constructor;
|
||||||
use nac3core::typecheck::typedef::{TypeEnum, Unifier};
|
use nac3core::typecheck::typedef::{TypeEnum, Unifier};
|
||||||
use nac3parser::{
|
use nac3parser::{
|
||||||
|
@ -664,34 +664,42 @@ impl Nac3 {
|
||||||
link_fn(&main)
|
link_fn(&main)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_llvm_target_machine(
|
/// Returns the [TargetTriple] used for compiling to [isa].
|
||||||
&self,
|
fn get_llvm_target_triple(isa: Isa) -> TargetTriple {
|
||||||
) -> TargetMachine {
|
match isa {
|
||||||
let (triple, features) = match self.isa {
|
Isa::Host => TargetMachine::get_default_triple(),
|
||||||
Isa::Host => (
|
Isa::RiscV32G | Isa::RiscV32IMA => TargetTriple::create("riscv32-unknown-linux"),
|
||||||
TargetMachine::get_default_triple(),
|
Isa::CortexA9 => TargetTriple::create("armv7-unknown-linux-gnueabihf"),
|
||||||
TargetMachine::get_host_cpu_features().to_string(),
|
|
||||||
),
|
|
||||||
Isa::RiscV32G => {
|
|
||||||
(TargetTriple::create("riscv32-unknown-linux"), "+a,+m,+f,+d".to_string())
|
|
||||||
}
|
}
|
||||||
Isa::RiscV32IMA => (TargetTriple::create("riscv32-unknown-linux"), "+a,+m".to_string()),
|
}
|
||||||
Isa::CortexA9 => (
|
|
||||||
TargetTriple::create("armv7-unknown-linux-gnueabihf"),
|
/// Returns the [String] representing the target features used for compiling to [isa].
|
||||||
"+dsp,+fp16,+neon,+vfp3,+long-calls".to_string(),
|
fn get_llvm_target_features(isa: Isa) -> String {
|
||||||
),
|
match isa {
|
||||||
};
|
Isa::Host => TargetMachine::get_host_cpu_features().to_string(),
|
||||||
let target =
|
Isa::RiscV32G => "+a,+m,+f,+d".to_string(),
|
||||||
Target::from_triple(&triple).expect("couldn't create target from target triple");
|
Isa::RiscV32IMA => "+a,+m".to_string(),
|
||||||
target
|
Isa::CortexA9 => "+dsp,+fp16,+neon,+vfp3,+long-calls".to_string(),
|
||||||
.create_target_machine(
|
}
|
||||||
&triple,
|
}
|
||||||
"",
|
|
||||||
&features,
|
/// Returns an instance of [CodeGenTargetMachineOptions] representing the target machine
|
||||||
self.llvm_options.opt_level,
|
/// options used for compiling to [isa].
|
||||||
RelocMode::PIC,
|
fn get_llvm_target_options(isa: Isa) -> CodeGenTargetMachineOptions {
|
||||||
CodeModel::Default,
|
CodeGenTargetMachineOptions {
|
||||||
)
|
triple: Nac3::get_llvm_target_triple(isa).as_str().to_string_lossy().into_owned(),
|
||||||
|
cpu: String::default(),
|
||||||
|
features: Nac3::get_llvm_target_features(isa),
|
||||||
|
reloc_mode: RelocMode::PIC,
|
||||||
|
..CodeGenTargetMachineOptions::from_host()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns an instance of [TargetMachine] used in compiling and linking of a program to the
|
||||||
|
/// target [isa].
|
||||||
|
fn get_llvm_target_machine(&self) -> TargetMachine {
|
||||||
|
Nac3::get_llvm_target_options(self.isa)
|
||||||
|
.create_target_machine(self.llvm_options.opt_level)
|
||||||
.expect("couldn't create target machine")
|
.expect("couldn't create target machine")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@ use inkwell::{
|
||||||
context::Context,
|
context::Context,
|
||||||
module::Module,
|
module::Module,
|
||||||
passes::{PassManager, PassManagerBuilder},
|
passes::{PassManager, PassManagerBuilder},
|
||||||
|
targets::{CodeModel, RelocMode, Target, TargetMachine, TargetTriple},
|
||||||
types::{AnyType, BasicType, BasicTypeEnum},
|
types::{AnyType, BasicType, BasicTypeEnum},
|
||||||
values::{BasicValueEnum, FunctionValue, PhiValue, PointerValue},
|
values::{BasicValueEnum, FunctionValue, PhiValue, PointerValue},
|
||||||
debug_info::{
|
debug_info::{
|
||||||
|
@ -68,6 +69,67 @@ pub struct CodeGenLLVMOptions {
|
||||||
pub emit_llvm: bool,
|
pub emit_llvm: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Additional options for code generation for the target machine.
|
||||||
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||||
|
pub struct CodeGenTargetMachineOptions {
|
||||||
|
/// The target machine triple.
|
||||||
|
pub triple: String,
|
||||||
|
/// The target machine CPU.
|
||||||
|
pub cpu: String,
|
||||||
|
/// Additional target machine features.
|
||||||
|
pub features: String,
|
||||||
|
/// Relocation mode for code generation.
|
||||||
|
pub reloc_mode: RelocMode,
|
||||||
|
/// Code model for code generation.
|
||||||
|
pub code_model: CodeModel,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CodeGenTargetMachineOptions {
|
||||||
|
|
||||||
|
/// Creates an instance of [CodeGenTargetMachineOptions] using the triple of the host machine.
|
||||||
|
/// Other options are set to defaults.
|
||||||
|
pub fn from_host_triple() -> CodeGenTargetMachineOptions {
|
||||||
|
CodeGenTargetMachineOptions {
|
||||||
|
triple: TargetMachine::get_default_triple().as_str().to_string_lossy().into_owned(),
|
||||||
|
cpu: String::default(),
|
||||||
|
features: String::default(),
|
||||||
|
reloc_mode: RelocMode::Default,
|
||||||
|
code_model: CodeModel::Default,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates an instance of [CodeGenTargetMachineOptions] using the properties of the host
|
||||||
|
/// machine. Other options are set to defaults.
|
||||||
|
pub fn from_host() -> CodeGenTargetMachineOptions {
|
||||||
|
CodeGenTargetMachineOptions {
|
||||||
|
cpu: TargetMachine::get_host_cpu_name().to_string(),
|
||||||
|
features: TargetMachine::get_host_cpu_features().to_string(),
|
||||||
|
..CodeGenTargetMachineOptions::from_host_triple()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates a [TargetMachine] using the target options specified by this struct.
|
||||||
|
///
|
||||||
|
/// See [Target::create_target_machine].
|
||||||
|
pub fn create_target_machine(
|
||||||
|
&self,
|
||||||
|
level: OptimizationLevel,
|
||||||
|
) -> Option<TargetMachine> {
|
||||||
|
let triple = TargetTriple::create(self.triple.as_str());
|
||||||
|
let target = Target::from_triple(&triple)
|
||||||
|
.expect(format!("could not create target from target triple {}", self.triple).as_str());
|
||||||
|
|
||||||
|
target.create_target_machine(
|
||||||
|
&triple,
|
||||||
|
self.cpu.as_str(),
|
||||||
|
self.features.as_str(),
|
||||||
|
level,
|
||||||
|
self.reloc_mode,
|
||||||
|
self.code_model
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct CodeGenContext<'ctx, 'a> {
|
pub struct CodeGenContext<'ctx, 'a> {
|
||||||
pub ctx: &'ctx Context,
|
pub ctx: &'ctx Context,
|
||||||
pub builder: Builder<'ctx>,
|
pub builder: Builder<'ctx>,
|
||||||
|
|
Loading…
Reference in New Issue