mirror of
https://github.com/edg-l/edlang.git
synced 2024-11-22 16:08:24 +00:00
todo
This commit is contained in:
parent
997f9b4dab
commit
b7355e2772
|
@ -6,7 +6,7 @@ use edlang_session::Session;
|
||||||
use inkwell::{
|
use inkwell::{
|
||||||
builder::{Builder, BuilderError},
|
builder::{Builder, BuilderError},
|
||||||
context::Context,
|
context::Context,
|
||||||
debug_info::{DICompileUnit, DebugInfoBuilder},
|
debug_info::{AsDIScope, DICompileUnit, DebugInfoBuilder},
|
||||||
module::Module,
|
module::Module,
|
||||||
targets::{InitializationConfig, Target, TargetData, TargetMachine},
|
targets::{InitializationConfig, Target, TargetData, TargetMachine},
|
||||||
types::{AnyType, BasicMetadataTypeEnum, BasicType},
|
types::{AnyType, BasicMetadataTypeEnum, BasicType},
|
||||||
|
@ -69,6 +69,7 @@ pub fn compile(session: &Session, program: &ProgramBody) -> Result<PathBuf, Box<
|
||||||
let filename = session.file_path.file_name().unwrap().to_string_lossy();
|
let filename = session.file_path.file_name().unwrap().to_string_lossy();
|
||||||
let dir = session.file_path.parent().unwrap().to_string_lossy();
|
let dir = session.file_path.parent().unwrap().to_string_lossy();
|
||||||
for module_id in program.top_level_modules.iter() {
|
for module_id in program.top_level_modules.iter() {
|
||||||
|
dbg!("here");
|
||||||
let module = ctx.program.modules.get(module_id).unwrap();
|
let module = ctx.program.modules.get(module_id).unwrap();
|
||||||
let llvm_module = context.create_module(&module.name);
|
let llvm_module = context.create_module(&module.name);
|
||||||
llvm_module.set_source_file_name(&filename);
|
llvm_module.set_source_file_name(&filename);
|
||||||
|
@ -114,13 +115,16 @@ pub fn compile(session: &Session, program: &ProgramBody) -> Result<PathBuf, Box<
|
||||||
inkwell::targets::FileType::Assembly,
|
inkwell::targets::FileType::Assembly,
|
||||||
&session.output_file.with_extension("asm"),
|
&session.output_file.with_extension("asm"),
|
||||||
)?;
|
)?;
|
||||||
|
dbg!("here");
|
||||||
machine.write_to_file(
|
machine.write_to_file(
|
||||||
&module_ctx.module,
|
&module_ctx.module,
|
||||||
inkwell::targets::FileType::Object,
|
inkwell::targets::FileType::Object,
|
||||||
&session.output_file.with_extension("o"),
|
&session.output_file.with_extension("o"),
|
||||||
)?;
|
)?;
|
||||||
|
dbg!("here");
|
||||||
// todo link modules together
|
// todo link modules together
|
||||||
llvm_modules.push(module_ctx.module);
|
llvm_modules.push(module_ctx.module);
|
||||||
|
dbg!("here");
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(session.output_file.with_extension("o"))
|
Ok(session.output_file.with_extension("o"))
|
||||||
|
@ -233,9 +237,46 @@ fn compile_fn(ctx: &ModuleCompileCtx, fn_id: DefId) -> Result<(), BuilderError>
|
||||||
info!("compiling block");
|
info!("compiling block");
|
||||||
ctx.builder.position_at_end(*llvm_block);
|
ctx.builder.position_at_end(*llvm_block);
|
||||||
for stmt in &block.statements {
|
for stmt in &block.statements {
|
||||||
|
if let Some(span) = stmt.span {
|
||||||
|
let (_, line, column) = ctx.ctx.session.source.get_offset_line(span.lo).unwrap();
|
||||||
|
let debug_loc = ctx.di_builder.create_debug_location(
|
||||||
|
ctx.ctx.context,
|
||||||
|
line as u32,
|
||||||
|
column as u32,
|
||||||
|
ctx.di_unit.as_debug_info_scope(),
|
||||||
|
None,
|
||||||
|
);
|
||||||
|
ctx.builder.set_current_debug_location(debug_loc);
|
||||||
|
}
|
||||||
|
// todo: setup locals with this ctx.di_builder.create_auto_variable(scope, name, file, line_no, ty, always_preserve, flags, align_in_bits)
|
||||||
|
|
||||||
info!("compiling stmt");
|
info!("compiling stmt");
|
||||||
match &stmt.kind {
|
match &stmt.kind {
|
||||||
ir::StatementKind::Assign(place, rvalue) => {
|
ir::StatementKind::Assign(place, rvalue) => {
|
||||||
|
let local = &body.locals[place.local];
|
||||||
|
if let Some(debug_name) = &local.debug_name {
|
||||||
|
let (_, line, column) = ctx
|
||||||
|
.ctx
|
||||||
|
.session
|
||||||
|
.source
|
||||||
|
.get_offset_line(local.span.unwrap().lo)
|
||||||
|
.unwrap();
|
||||||
|
let debug_loc = ctx.di_builder.create_debug_location(
|
||||||
|
ctx.ctx.context,
|
||||||
|
line as u32,
|
||||||
|
column as u32,
|
||||||
|
ctx.di_unit.as_debug_info_scope(), // todo correct scope
|
||||||
|
None,
|
||||||
|
);
|
||||||
|
ctx.builder.set_current_debug_location(debug_loc);
|
||||||
|
ctx.di_builder.insert_declare_at_end(
|
||||||
|
locals[&place.local],
|
||||||
|
None, // todo var info
|
||||||
|
None,
|
||||||
|
debug_loc,
|
||||||
|
*llvm_block,
|
||||||
|
);
|
||||||
|
}
|
||||||
let (value, _value_ty) = compile_rvalue(ctx, fn_id, &locals, rvalue)?;
|
let (value, _value_ty) = compile_rvalue(ctx, fn_id, &locals, rvalue)?;
|
||||||
ctx.builder
|
ctx.builder
|
||||||
.build_store(*locals.get(&place.local).unwrap(), value)?;
|
.build_store(*locals.get(&place.local).unwrap(), value)?;
|
||||||
|
|
|
@ -5,21 +5,6 @@ use std::path::PathBuf;
|
||||||
|
|
||||||
use edlang_session::Session;
|
use edlang_session::Session;
|
||||||
use ir::ProgramBody;
|
use ir::ProgramBody;
|
||||||
/*
|
|
||||||
use llvm_sys::{
|
|
||||||
core::{LLVMContextCreate, LLVMContextDispose, LLVMDisposeMessage, LLVMDisposeModule},
|
|
||||||
target::{
|
|
||||||
LLVM_InitializeAllAsmPrinters, LLVM_InitializeAllTargetInfos, LLVM_InitializeAllTargetMCs,
|
|
||||||
LLVM_InitializeAllTargets,
|
|
||||||
},
|
|
||||||
target_machine::{
|
|
||||||
LLVMCodeGenFileType, LLVMCodeGenOptLevel, LLVMCodeModel, LLVMCreateTargetMachine,
|
|
||||||
LLVMDisposeTargetMachine, LLVMGetDefaultTargetTriple, LLVMGetHostCPUFeatures,
|
|
||||||
LLVMGetHostCPUName, LLVMGetTargetFromTriple, LLVMRelocMode, LLVMTargetMachineEmitToFile,
|
|
||||||
LLVMTargetRef,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
|
|
||||||
pub mod codegen;
|
pub mod codegen;
|
||||||
pub mod linker;
|
pub mod linker;
|
||||||
|
@ -30,128 +15,3 @@ pub fn compile(
|
||||||
) -> Result<PathBuf, Box<dyn std::error::Error>> {
|
) -> Result<PathBuf, Box<dyn std::error::Error>> {
|
||||||
codegen::compile(session, program)
|
codegen::compile(session, program)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Converts a module to an object.
|
|
||||||
// The object will be written to the specified target path.
|
|
||||||
// TODO: error handling
|
|
||||||
//
|
|
||||||
// Returns the path to the object.ç
|
|
||||||
|
|
||||||
/*
|
|
||||||
pub fn compile_to_object(
|
|
||||||
session: &Session,
|
|
||||||
module: &MeliorModule,
|
|
||||||
) -> Result<PathBuf, Box<dyn std::error::Error>> {
|
|
||||||
tracing::debug!("Compiling to object file");
|
|
||||||
if !session.target_dir.exists() {
|
|
||||||
std::fs::create_dir_all(&session.target_dir)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
let target_file = session
|
|
||||||
.file_path
|
|
||||||
.clone()
|
|
||||||
.file_stem()
|
|
||||||
.unwrap()
|
|
||||||
.to_string_lossy()
|
|
||||||
.to_string();
|
|
||||||
let target_file = PathBuf::from(target_file).with_extension("o");
|
|
||||||
tracing::debug!("Target file: {:?}", target_file);
|
|
||||||
|
|
||||||
let target_path = session.target_dir.join(target_file);
|
|
||||||
|
|
||||||
// TODO: Rework so you can specify target and host features, etc.
|
|
||||||
// Right now it compiles for the native cpu feature set and arch.
|
|
||||||
static INITIALIZED: OnceLock<()> = OnceLock::new();
|
|
||||||
|
|
||||||
INITIALIZED.get_or_init(|| unsafe {
|
|
||||||
LLVM_InitializeAllTargets();
|
|
||||||
LLVM_InitializeAllTargetInfos();
|
|
||||||
LLVM_InitializeAllTargetMCs();
|
|
||||||
LLVM_InitializeAllAsmPrinters();
|
|
||||||
tracing::debug!("initialized llvm targets");
|
|
||||||
});
|
|
||||||
|
|
||||||
unsafe {
|
|
||||||
let llvm_context = LLVMContextCreate();
|
|
||||||
|
|
||||||
let op = module.as_operation().to_raw();
|
|
||||||
|
|
||||||
let llvm_module = mlirTranslateModuleToLLVMIR(op, llvm_context);
|
|
||||||
|
|
||||||
let mut null = null_mut();
|
|
||||||
let mut error_buffer = addr_of_mut!(null);
|
|
||||||
|
|
||||||
let target_triple = LLVMGetDefaultTargetTriple();
|
|
||||||
tracing::debug!("Target triple: {:?}", CStr::from_ptr(target_triple));
|
|
||||||
|
|
||||||
let target_cpu = LLVMGetHostCPUName();
|
|
||||||
tracing::debug!("Target CPU: {:?}", CStr::from_ptr(target_cpu));
|
|
||||||
|
|
||||||
let target_cpu_features = LLVMGetHostCPUFeatures();
|
|
||||||
tracing::debug!(
|
|
||||||
"Target CPU Features: {:?}",
|
|
||||||
CStr::from_ptr(target_cpu_features)
|
|
||||||
);
|
|
||||||
|
|
||||||
let mut target: MaybeUninit<LLVMTargetRef> = MaybeUninit::uninit();
|
|
||||||
|
|
||||||
if LLVMGetTargetFromTriple(target_triple, target.as_mut_ptr(), error_buffer) != 0 {
|
|
||||||
let error = CStr::from_ptr(*error_buffer);
|
|
||||||
let err = error.to_string_lossy().to_string();
|
|
||||||
tracing::error!("error getting target triple: {}", err);
|
|
||||||
LLVMDisposeMessage(*error_buffer);
|
|
||||||
panic!("{err}")
|
|
||||||
} else if !(*error_buffer).is_null() {
|
|
||||||
LLVMDisposeMessage(*error_buffer);
|
|
||||||
error_buffer = addr_of_mut!(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
let target = target.assume_init();
|
|
||||||
|
|
||||||
let machine = LLVMCreateTargetMachine(
|
|
||||||
target,
|
|
||||||
target_triple.cast(),
|
|
||||||
target_cpu.cast(),
|
|
||||||
target_cpu_features.cast(),
|
|
||||||
match session.optlevel {
|
|
||||||
OptLevel::None => LLVMCodeGenOptLevel::LLVMCodeGenLevelNone,
|
|
||||||
OptLevel::Less => LLVMCodeGenOptLevel::LLVMCodeGenLevelLess,
|
|
||||||
OptLevel::Default => LLVMCodeGenOptLevel::LLVMCodeGenLevelDefault,
|
|
||||||
OptLevel::Aggressive => LLVMCodeGenOptLevel::LLVMCodeGenLevelAggressive,
|
|
||||||
},
|
|
||||||
if session.library {
|
|
||||||
LLVMRelocMode::LLVMRelocDynamicNoPic
|
|
||||||
} else {
|
|
||||||
LLVMRelocMode::LLVMRelocDefault
|
|
||||||
},
|
|
||||||
LLVMCodeModel::LLVMCodeModelDefault,
|
|
||||||
);
|
|
||||||
|
|
||||||
let filename = CString::new(target_path.as_os_str().to_string_lossy().as_bytes()).unwrap();
|
|
||||||
tracing::debug!("filename to llvm: {:?}", filename);
|
|
||||||
let ok = LLVMTargetMachineEmitToFile(
|
|
||||||
machine,
|
|
||||||
llvm_module,
|
|
||||||
filename.as_ptr().cast_mut(),
|
|
||||||
LLVMCodeGenFileType::LLVMObjectFile, // object (binary) or assembly (textual)
|
|
||||||
error_buffer,
|
|
||||||
);
|
|
||||||
|
|
||||||
if ok != 0 {
|
|
||||||
let error = CStr::from_ptr(*error_buffer);
|
|
||||||
let err = error.to_string_lossy().to_string();
|
|
||||||
tracing::error!("error emitting to file: {:?}", err);
|
|
||||||
LLVMDisposeMessage(*error_buffer);
|
|
||||||
panic!("{err}")
|
|
||||||
} else if !(*error_buffer).is_null() {
|
|
||||||
LLVMDisposeMessage(*error_buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
LLVMDisposeTargetMachine(machine);
|
|
||||||
LLVMDisposeModule(llvm_module);
|
|
||||||
LLVMContextDispose(llvm_context);
|
|
||||||
|
|
||||||
Ok(target_path)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
|
@ -13,6 +13,7 @@ pub fn prepass_module(mut ctx: BuildCtx, mod_def: &ast::Module) -> BuildCtx {
|
||||||
ctx.body
|
ctx.body
|
||||||
.top_level_module_names
|
.top_level_module_names
|
||||||
.insert(mod_def.name.name.clone(), module_id);
|
.insert(mod_def.name.name.clone(), module_id);
|
||||||
|
ctx.body.top_level_modules.push(module_id);
|
||||||
|
|
||||||
ctx.body.modules.insert(
|
ctx.body.modules.insert(
|
||||||
module_id,
|
module_id,
|
||||||
|
|
Loading…
Reference in a new issue