This commit is contained in:
Edgar 2024-02-08 12:14:18 +01:00
parent 997f9b4dab
commit b7355e2772
No known key found for this signature in database
GPG key ID: 70ADAE8F35904387
3 changed files with 43 additions and 141 deletions

View file

@ -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)?;

View file

@ -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)
}
}
*/

View file

@ -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,