use crate::{AssemblyIr, ModuleGroupId, ModulePartition, TargetAssembly};
use by_address::ByAddress;
use inkwell::targets::{CodeModel, InitializationConfig, RelocMode, Target, TargetTriple};
use std::sync::Arc;
#[salsa::query_group(CodeGenDatabaseStorage)]
pub trait CodeGenDatabase:
mun_hir::HirDatabase + mun_hir::Upcast<dyn mun_hir::HirDatabase>
{
#[salsa::input]
fn optimization_level(&self) -> inkwell::OptimizationLevel;
#[salsa::invoke(crate::module_partition::build_partition)]
fn module_partition(&self) -> Arc<ModulePartition>;
fn target_machine(&self) -> ByAddress<Arc<inkwell::targets::TargetMachine>>;
#[salsa::invoke(crate::assembly::build_assembly_ir)]
fn assembly_ir(&self, module_group: ModuleGroupId) -> Arc<AssemblyIr>;
#[salsa::invoke(crate::assembly::build_target_assembly)]
fn target_assembly(&self, module_group: ModuleGroupId) -> Arc<TargetAssembly>;
}
fn target_machine(db: &dyn CodeGenDatabase) -> ByAddress<Arc<inkwell::targets::TargetMachine>> {
let target = db.target();
Target::initialize_x86(&InitializationConfig::default());
Target::initialize_aarch64(&InitializationConfig::default());
let target_triple = TargetTriple::create(&db.target().llvm_target);
let llvm_target = Target::from_triple(&target_triple)
.expect("could not find llvm target tripple for Mun target");
let target_machine = llvm_target
.create_target_machine(
&target_triple,
&target.options.cpu,
&target.options.features,
db.optimization_level(),
RelocMode::PIC,
CodeModel::Default,
)
.expect("could not create llvm target machine");
ByAddress(Arc::new(target_machine))
}