mirror of
https://github.com/edg-l/edlang.git
synced 2024-11-22 16:08: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]
|
[dependencies]
|
||||||
bumpalo = { version = "3.14.0", features = ["std"] }
|
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_parser = { version = "0.1.0", path = "../edlang_parser" }
|
||||||
edlang_session = { version = "0.1.0", path = "../edlang_session" }
|
edlang_session = { version = "0.1.0", path = "../edlang_session" }
|
||||||
llvm-sys = "170.0.1"
|
llvm-sys = "170.0.1"
|
||||||
melior = { version = "0.15.2", features = ["ods-dialects"] }
|
inkwell = { git = "https://github.com/TheDan64/inkwell", rev = "0cdaa34bd612464f310b3fdefa00a75d1324687d", features = ["llvm17-0"] }
|
||||||
mlir-sys = "0.2.1"
|
|
||||||
tracing = { workspace = true }
|
tracing = { workspace = true }
|
||||||
|
|
||||||
[build-dependencies]
|
[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)]
|
#![allow(clippy::too_many_arguments)]
|
||||||
|
|
||||||
|
use edlang_ir as ir;
|
||||||
use std::{
|
use std::{
|
||||||
|
collections::HashMap,
|
||||||
ffi::{CStr, CString},
|
ffi::{CStr, CString},
|
||||||
mem::MaybeUninit,
|
mem::MaybeUninit,
|
||||||
path::PathBuf,
|
path::PathBuf,
|
||||||
|
@ -8,9 +10,10 @@ use std::{
|
||||||
sync::OnceLock,
|
sync::OnceLock,
|
||||||
};
|
};
|
||||||
|
|
||||||
use context::Context;
|
|
||||||
use edlang_ast::Module;
|
|
||||||
use edlang_session::{OptLevel, Session};
|
use edlang_session::{OptLevel, Session};
|
||||||
|
use inkwell::context::Context;
|
||||||
|
use ir::DefId;
|
||||||
|
/*
|
||||||
use llvm_sys::{
|
use llvm_sys::{
|
||||||
core::{LLVMContextCreate, LLVMContextDispose, LLVMDisposeMessage, LLVMDisposeModule},
|
core::{LLVMContextCreate, LLVMContextDispose, LLVMDisposeMessage, LLVMDisposeModule},
|
||||||
target::{
|
target::{
|
||||||
|
@ -24,41 +27,26 @@ use llvm_sys::{
|
||||||
LLVMTargetRef,
|
LLVMTargetRef,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use melior::ir::{operation::OperationPrintingFlags, Module as MeliorModule};
|
*/
|
||||||
|
|
||||||
use crate::ffi::mlirTranslateModuleToLLVMIR;
|
|
||||||
|
|
||||||
pub mod codegen;
|
pub mod codegen;
|
||||||
mod context;
|
|
||||||
mod ffi;
|
|
||||||
pub mod linker;
|
pub mod linker;
|
||||||
|
|
||||||
pub fn compile_mlir(
|
pub fn compile(
|
||||||
session: &Session,
|
session: &Session,
|
||||||
program: &Module,
|
modules: &HashMap<DefId, ir::ModuleBody>,
|
||||||
) -> Result<String, Box<dyn std::error::Error>> {
|
symbols: HashMap<DefId, String>,
|
||||||
let context = Context::new();
|
) -> Result<PathBuf, Box<dyn std::error::Error>> {
|
||||||
let mlir_module = context.compile(session, program)?;
|
codegen::compile(session, modules, &symbols)
|
||||||
|
|
||||||
Ok(mlir_module
|
|
||||||
.as_operation()
|
|
||||||
.to_string_with_flags(OperationPrintingFlags::new().enable_debug_info(true, false))?)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn compile(session: &Session, program: &Module) -> Result<PathBuf, Box<dyn std::error::Error>> {
|
// Converts a module to an object.
|
||||||
let context = Context::new();
|
// The object will be written to the specified target path.
|
||||||
let mlir_module = context.compile(session, program)?;
|
// 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(
|
pub fn compile_to_object(
|
||||||
session: &Session,
|
session: &Session,
|
||||||
module: &MeliorModule,
|
module: &MeliorModule,
|
||||||
|
@ -175,3 +163,4 @@ pub fn compile_to_object(
|
||||||
Ok(target_path)
|
Ok(target_path)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
|
@ -85,19 +85,14 @@ pub fn main() -> Result<(), Box<dyn Error>> {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
let (_symbols, module_irs) = lower_modules(&[module.clone()]);
|
let (symbols, module_irs) = lower_modules(&[module.clone()]);
|
||||||
|
|
||||||
if args.ir {
|
if args.ir {
|
||||||
println!("{:#?}", module_irs);
|
println!("{:#?}", module_irs);
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
if args.mlir {
|
let object_path = edlang_codegen_mlir::compile(&session, &module_irs, symbols)?;
|
||||||
println!("{}", edlang_codegen_mlir::compile_mlir(&session, &module)?);
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
|
|
||||||
let object_path = edlang_codegen_mlir::compile(&session, &module)?;
|
|
||||||
|
|
||||||
if session.library {
|
if session.library {
|
||||||
link_shared_lib(&object_path, &session.output_file.with_extension("so"))?;
|
link_shared_lib(&object_path, &session.output_file.with_extension("so"))?;
|
||||||
|
|
|
@ -22,6 +22,15 @@ pub struct DefId {
|
||||||
pub id: usize,
|
pub id: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl DefId {
|
||||||
|
pub fn get_module_defid(&self) -> Self {
|
||||||
|
Self {
|
||||||
|
module_id: self.module_id,
|
||||||
|
id: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Body {
|
pub struct Body {
|
||||||
pub def_id: DefId,
|
pub def_id: DefId,
|
||||||
|
@ -33,6 +42,24 @@ pub struct Body {
|
||||||
pub fn_span: Span,
|
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)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct DebugInfo {
|
pub struct DebugInfo {
|
||||||
pub id: usize,
|
pub id: usize,
|
||||||
|
|
|
@ -12,7 +12,7 @@ impl IdGenerator {
|
||||||
pub const fn new(module_id: usize) -> Self {
|
pub const fn new(module_id: usize) -> Self {
|
||||||
Self {
|
Self {
|
||||||
current_id: 0,
|
current_id: 0,
|
||||||
module_id: 0,
|
module_id,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,9 @@ use ir::{ConstData, ConstKind, DefId, Local, Operand, Place, Statement, Terminat
|
||||||
|
|
||||||
mod common;
|
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();
|
let mut ctx = BuildCtx::default();
|
||||||
|
|
||||||
for m in modules {
|
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();
|
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
|
// todo: maybe should do a prepass here populating all symbols
|
||||||
|
|
||||||
for module in modules {
|
for module in modules {
|
||||||
let ir;
|
let ir;
|
||||||
(ctx, ir) = lower_module(ctx, module);
|
(ctx, ir) = lower_module(ctx, module);
|
||||||
lowered_modules.push(ir);
|
lowered_modules.insert(ir.module_id, ir);
|
||||||
}
|
}
|
||||||
|
|
||||||
(ctx.symbol_names, lowered_modules)
|
(ctx.symbol_names, lowered_modules)
|
||||||
|
|
|
@ -1,13 +1,8 @@
|
||||||
mod Main {
|
mod Main {
|
||||||
|
|
||||||
fn main(argc: i32) -> i32 {
|
pub fn main(argc: i32) -> i32 {
|
||||||
let mut x: i32 = 2;
|
let mut x: i32 = 2;
|
||||||
x = 4;
|
x = 4;
|
||||||
let y: i32 = other(2);
|
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn other(a: i32) -> i32 {
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue