mirror of
https://github.com/edg-l/edlang.git
synced 2024-11-22 07:58:24 +00:00
compile
This commit is contained in:
parent
cdc52cef39
commit
8f1c094b60
764
Cargo.lock
generated
764
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
|
@ -12,12 +12,11 @@ categories = ["compilers"]
|
|||
|
||||
[dependencies]
|
||||
bumpalo = { version = "3.14.0", features = ["std"] }
|
||||
edlang_ast = { version = "0.1.0", path = "../edlang_ast" }
|
||||
edlang_ir = { version = "0.1.0", path = "../edlang_ir" }
|
||||
edlang_parser = { version = "0.1.0", path = "../edlang_parser" }
|
||||
edlang_session = { version = "0.1.0", path = "../edlang_session" }
|
||||
llvm-sys = "170.0.1"
|
||||
melior = { version = "0.15.2", features = ["ods-dialects"] }
|
||||
mlir-sys = "0.2.1"
|
||||
inkwell = { git = "https://github.com/TheDan64/inkwell", rev = "0cdaa34bd612464f310b3fdefa00a75d1324687d", features = ["llvm17-0"] }
|
||||
tracing = { workspace = true }
|
||||
|
||||
[build-dependencies]
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,91 +0,0 @@
|
|||
use std::error::Error;
|
||||
|
||||
use edlang_ast::Module;
|
||||
use edlang_session::Session;
|
||||
use melior::{
|
||||
dialect::DialectRegistry,
|
||||
ir::{operation::OperationPrintingFlags, Location, Module as MeliorModule},
|
||||
pass::{self, PassManager},
|
||||
utility::{register_all_dialects, register_all_llvm_translations, register_all_passes},
|
||||
Context as MeliorContext,
|
||||
};
|
||||
|
||||
#[derive(Debug, Eq, PartialEq)]
|
||||
pub struct Context {
|
||||
melior_context: MeliorContext,
|
||||
}
|
||||
|
||||
impl Default for Context {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl Context {
|
||||
pub fn new() -> Self {
|
||||
let melior_context = initialize_mlir();
|
||||
Self { melior_context }
|
||||
}
|
||||
|
||||
pub fn compile(
|
||||
&self,
|
||||
session: &Session,
|
||||
module: &Module,
|
||||
) -> Result<MeliorModule, Box<dyn Error>> {
|
||||
let file_path = session.file_path.display().to_string();
|
||||
let location = Location::new(&self.melior_context, &file_path, 0, 0);
|
||||
|
||||
let mut melior_module = MeliorModule::new(location);
|
||||
|
||||
super::codegen::compile_module(session, &self.melior_context, &melior_module, module)?;
|
||||
|
||||
assert!(melior_module.as_operation().verify());
|
||||
|
||||
tracing::debug!(
|
||||
"MLIR Code before passes:\n{}",
|
||||
melior_module.as_operation().to_string_with_flags(
|
||||
OperationPrintingFlags::new().enable_debug_info(true, true)
|
||||
)?
|
||||
);
|
||||
|
||||
// TODO: Add proper error handling.
|
||||
self.run_pass_manager(&mut melior_module)?;
|
||||
|
||||
tracing::debug!(
|
||||
"MLIR Code after passes:\n{}",
|
||||
melior_module.as_operation().to_string_with_flags(
|
||||
OperationPrintingFlags::new().enable_debug_info(true, true)
|
||||
)?
|
||||
);
|
||||
|
||||
Ok(melior_module)
|
||||
}
|
||||
|
||||
fn run_pass_manager(&self, module: &mut MeliorModule) -> Result<(), melior::Error> {
|
||||
let pass_manager = PassManager::new(&self.melior_context);
|
||||
pass_manager.enable_verifier(true);
|
||||
pass_manager.add_pass(pass::transform::create_canonicalizer());
|
||||
pass_manager.add_pass(pass::conversion::create_scf_to_control_flow());
|
||||
pass_manager.add_pass(pass::conversion::create_arith_to_llvm());
|
||||
pass_manager.add_pass(pass::conversion::create_control_flow_to_llvm());
|
||||
pass_manager.add_pass(pass::conversion::create_func_to_llvm());
|
||||
pass_manager.add_pass(pass::conversion::create_index_to_llvm());
|
||||
pass_manager.add_pass(pass::conversion::create_finalize_mem_ref_to_llvm());
|
||||
pass_manager.add_pass(pass::conversion::create_reconcile_unrealized_casts());
|
||||
pass_manager.run(module)
|
||||
}
|
||||
}
|
||||
|
||||
/// Initialize an MLIR context.
|
||||
pub fn initialize_mlir() -> MeliorContext {
|
||||
let context = MeliorContext::new();
|
||||
context.append_dialect_registry(&{
|
||||
let registry = DialectRegistry::new();
|
||||
register_all_dialects(®istry);
|
||||
registry
|
||||
});
|
||||
context.load_all_available_dialects();
|
||||
register_all_passes();
|
||||
register_all_llvm_translations(&context);
|
||||
context
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
use llvm_sys::prelude::{LLVMContextRef, LLVMModuleRef};
|
||||
|
||||
extern "C" {
|
||||
/// Translate operation that satisfies LLVM dialect module requirements into an LLVM IR module living in the given context.
|
||||
/// This translates operations from any dilalect that has a registered implementation of LLVMTranslationDialectInterface.
|
||||
pub fn mlirTranslateModuleToLLVMIR(
|
||||
module_operation_ptr: mlir_sys::MlirOperation,
|
||||
llvm_context: LLVMContextRef,
|
||||
) -> LLVMModuleRef;
|
||||
}
|
|
@ -1,6 +1,8 @@
|
|||
#![allow(clippy::too_many_arguments)]
|
||||
|
||||
use edlang_ir as ir;
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
ffi::{CStr, CString},
|
||||
mem::MaybeUninit,
|
||||
path::PathBuf,
|
||||
|
@ -8,9 +10,10 @@ use std::{
|
|||
sync::OnceLock,
|
||||
};
|
||||
|
||||
use context::Context;
|
||||
use edlang_ast::Module;
|
||||
use edlang_session::{OptLevel, Session};
|
||||
use inkwell::context::Context;
|
||||
use ir::DefId;
|
||||
/*
|
||||
use llvm_sys::{
|
||||
core::{LLVMContextCreate, LLVMContextDispose, LLVMDisposeMessage, LLVMDisposeModule},
|
||||
target::{
|
||||
|
@ -24,41 +27,26 @@ use llvm_sys::{
|
|||
LLVMTargetRef,
|
||||
},
|
||||
};
|
||||
use melior::ir::{operation::OperationPrintingFlags, Module as MeliorModule};
|
||||
|
||||
use crate::ffi::mlirTranslateModuleToLLVMIR;
|
||||
*/
|
||||
|
||||
pub mod codegen;
|
||||
mod context;
|
||||
mod ffi;
|
||||
pub mod linker;
|
||||
|
||||
pub fn compile_mlir(
|
||||
pub fn compile(
|
||||
session: &Session,
|
||||
program: &Module,
|
||||
) -> Result<String, Box<dyn std::error::Error>> {
|
||||
let context = Context::new();
|
||||
let mlir_module = context.compile(session, program)?;
|
||||
|
||||
Ok(mlir_module
|
||||
.as_operation()
|
||||
.to_string_with_flags(OperationPrintingFlags::new().enable_debug_info(true, false))?)
|
||||
modules: &HashMap<DefId, ir::ModuleBody>,
|
||||
symbols: HashMap<DefId, String>,
|
||||
) -> Result<PathBuf, Box<dyn std::error::Error>> {
|
||||
codegen::compile(session, modules, &symbols)
|
||||
}
|
||||
|
||||
pub fn compile(session: &Session, program: &Module) -> Result<PathBuf, Box<dyn std::error::Error>> {
|
||||
let context = Context::new();
|
||||
let mlir_module = context.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.ç
|
||||
|
||||
let object_path = compile_to_object(session, &mlir_module)?;
|
||||
|
||||
Ok(object_path)
|
||||
}
|
||||
|
||||
/// 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,
|
||||
|
@ -175,3 +163,4 @@ pub fn compile_to_object(
|
|||
Ok(target_path)
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
|
|
@ -85,19 +85,14 @@ pub fn main() -> Result<(), Box<dyn Error>> {
|
|||
return Ok(());
|
||||
}
|
||||
|
||||
let (_symbols, module_irs) = lower_modules(&[module.clone()]);
|
||||
let (symbols, module_irs) = lower_modules(&[module.clone()]);
|
||||
|
||||
if args.ir {
|
||||
println!("{:#?}", module_irs);
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
if args.mlir {
|
||||
println!("{}", edlang_codegen_mlir::compile_mlir(&session, &module)?);
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let object_path = edlang_codegen_mlir::compile(&session, &module)?;
|
||||
let object_path = edlang_codegen_mlir::compile(&session, &module_irs, symbols)?;
|
||||
|
||||
if session.library {
|
||||
link_shared_lib(&object_path, &session.output_file.with_extension("so"))?;
|
||||
|
|
|
@ -22,6 +22,15 @@ pub struct DefId {
|
|||
pub id: usize,
|
||||
}
|
||||
|
||||
impl DefId {
|
||||
pub fn get_module_defid(&self) -> Self {
|
||||
Self {
|
||||
module_id: self.module_id,
|
||||
id: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Body {
|
||||
pub def_id: DefId,
|
||||
|
@ -33,6 +42,24 @@ pub struct Body {
|
|||
pub fn_span: Span,
|
||||
}
|
||||
|
||||
impl Body {
|
||||
pub fn get_args(&self) -> SmallVec<[Local; 4]> {
|
||||
let mut args = SmallVec::default();
|
||||
|
||||
for x in &self.locals {
|
||||
if let LocalKind::Arg = x.kind {
|
||||
args.push(x.clone());
|
||||
}
|
||||
}
|
||||
|
||||
args
|
||||
}
|
||||
|
||||
pub fn get_return_local(&self) -> Local {
|
||||
self.locals[0].clone()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct DebugInfo {
|
||||
pub id: usize,
|
||||
|
|
|
@ -12,7 +12,7 @@ impl IdGenerator {
|
|||
pub const fn new(module_id: usize) -> Self {
|
||||
Self {
|
||||
current_id: 0,
|
||||
module_id: 0,
|
||||
module_id,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,9 @@ use ir::{ConstData, ConstKind, DefId, Local, Operand, Place, Statement, Terminat
|
|||
|
||||
mod common;
|
||||
|
||||
pub fn lower_modules(modules: &[ast::Module]) -> (HashMap<DefId, String>, Vec<ir::ModuleBody>) {
|
||||
pub fn lower_modules(
|
||||
modules: &[ast::Module],
|
||||
) -> (HashMap<DefId, String>, HashMap<DefId, ir::ModuleBody>) {
|
||||
let mut ctx = BuildCtx::default();
|
||||
|
||||
for m in modules {
|
||||
|
@ -28,14 +30,14 @@ pub fn lower_modules(modules: &[ast::Module]) -> (HashMap<DefId, String>, Vec<ir
|
|||
ctx.gen.next_module_defid();
|
||||
}
|
||||
|
||||
let mut lowered_modules = Vec::with_capacity(modules.len());
|
||||
let mut lowered_modules = HashMap::with_capacity(modules.len());
|
||||
|
||||
// todo: maybe should do a prepass here populating all symbols
|
||||
|
||||
for module in modules {
|
||||
let ir;
|
||||
(ctx, ir) = lower_module(ctx, module);
|
||||
lowered_modules.push(ir);
|
||||
lowered_modules.insert(ir.module_id, ir);
|
||||
}
|
||||
|
||||
(ctx.symbol_names, lowered_modules)
|
||||
|
|
|
@ -1,13 +1,8 @@
|
|||
mod Main {
|
||||
|
||||
fn main(argc: i32) -> i32 {
|
||||
pub fn main(argc: i32) -> i32 {
|
||||
let mut x: i32 = 2;
|
||||
x = 4;
|
||||
let y: i32 = other(2);
|
||||
return x;
|
||||
}
|
||||
|
||||
fn other(a: i32) -> i32 {
|
||||
return a;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue