Make linking modules together work, fix printing modules
This commit is contained in:
parent
848347e4a8
commit
2b47c4efc7
@ -202,6 +202,10 @@ impl Builder {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn find_module<'ctx>(&'ctx self, value: ModuleValue) -> ModuleHolder {
|
||||
unsafe { self.modules.borrow().get_unchecked(value.0).clone() }
|
||||
}
|
||||
|
||||
pub(crate) fn get_modules(&self) -> Rc<RefCell<Vec<ModuleHolder>>> {
|
||||
self.modules.clone()
|
||||
}
|
||||
|
@ -2,12 +2,13 @@
|
||||
//! LLIR ([`Context`]) into LLVM IR. This module is the only one that interfaces
|
||||
//! with the LLVM API.
|
||||
|
||||
use std::{collections::HashMap, ffi::CString, ptr::null_mut};
|
||||
use std::{collections::HashMap, ffi::CString, marker::PhantomData, ptr::null_mut};
|
||||
|
||||
use llvm_sys::{
|
||||
LLVMIntPredicate, LLVMLinkage,
|
||||
analysis::LLVMVerifyModule,
|
||||
core::*,
|
||||
linker::LLVMLinkModules2,
|
||||
prelude::*,
|
||||
target::{
|
||||
LLVM_InitializeAllAsmParsers, LLVM_InitializeAllAsmPrinters, LLVM_InitializeAllTargetInfos,
|
||||
@ -34,8 +35,87 @@ pub struct LLVMContext {
|
||||
builder_ref: LLVMBuilderRef,
|
||||
}
|
||||
|
||||
impl Drop for LLVMContext {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
LLVMDisposeBuilder(self.builder_ref);
|
||||
LLVMContextDispose(self.context_ref);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct CompiledModule {
|
||||
module_ref: LLVMModuleRef,
|
||||
_context: LLVMContext,
|
||||
}
|
||||
|
||||
impl CompiledModule {
|
||||
pub fn output(&self) {
|
||||
unsafe {
|
||||
LLVM_InitializeAllTargets();
|
||||
LLVM_InitializeAllTargetInfos();
|
||||
LLVM_InitializeAllTargetMCs();
|
||||
LLVM_InitializeAllAsmParsers();
|
||||
LLVM_InitializeAllAsmPrinters();
|
||||
|
||||
let triple = LLVMGetDefaultTargetTriple();
|
||||
|
||||
let mut target: _ = null_mut();
|
||||
let mut err = ErrorMessageHolder::null();
|
||||
LLVMGetTargetFromTriple(triple, &mut target, err.borrow_mut());
|
||||
println!("{:?}, {:?}", from_cstring(triple), target);
|
||||
err.into_result().unwrap();
|
||||
|
||||
let target_machine = LLVMCreateTargetMachine(
|
||||
target,
|
||||
triple,
|
||||
c"generic".as_ptr(),
|
||||
c"".as_ptr(),
|
||||
llvm_sys::target_machine::LLVMCodeGenOptLevel::LLVMCodeGenLevelNone,
|
||||
llvm_sys::target_machine::LLVMRelocMode::LLVMRelocDefault,
|
||||
llvm_sys::target_machine::LLVMCodeModel::LLVMCodeModelDefault,
|
||||
);
|
||||
|
||||
let data_layout = LLVMCreateTargetDataLayout(target_machine);
|
||||
LLVMSetTarget(self.module_ref, triple);
|
||||
LLVMSetModuleDataLayout(self.module_ref, data_layout);
|
||||
|
||||
let mut err = ErrorMessageHolder::null();
|
||||
LLVMVerifyModule(
|
||||
self.module_ref,
|
||||
llvm_sys::analysis::LLVMVerifierFailureAction::LLVMPrintMessageAction,
|
||||
err.borrow_mut(),
|
||||
);
|
||||
err.into_result().unwrap();
|
||||
|
||||
let mut err = ErrorMessageHolder::null();
|
||||
LLVMTargetMachineEmitToFile(
|
||||
target_machine,
|
||||
self.module_ref,
|
||||
CString::new("hello.asm").unwrap().into_raw(),
|
||||
LLVMCodeGenFileType::LLVMAssemblyFile,
|
||||
err.borrow_mut(),
|
||||
);
|
||||
err.into_result().unwrap();
|
||||
|
||||
let mut err = ErrorMessageHolder::null();
|
||||
LLVMTargetMachineEmitToFile(
|
||||
target_machine,
|
||||
self.module_ref,
|
||||
CString::new("hello.o").unwrap().into_raw(),
|
||||
LLVMCodeGenFileType::LLVMObjectFile,
|
||||
err.borrow_mut(),
|
||||
);
|
||||
err.into_result().unwrap();
|
||||
|
||||
let module_str = from_cstring(LLVMPrintModuleToString(self.module_ref));
|
||||
println!("{}", module_str.unwrap());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Context {
|
||||
pub fn compile(&self) {
|
||||
pub fn compile(&self) -> CompiledModule {
|
||||
unsafe {
|
||||
let context_ref = LLVMContextCreate();
|
||||
|
||||
@ -44,12 +124,31 @@ impl Context {
|
||||
builder_ref: LLVMCreateBuilderInContext(context_ref),
|
||||
};
|
||||
|
||||
for holder in self.builder.get_modules().borrow().iter() {
|
||||
holder.compile(&context, &self.builder);
|
||||
let module_holders = self.builder.get_modules();
|
||||
|
||||
let main_module = module_holders
|
||||
.borrow()
|
||||
.iter()
|
||||
.find(|m| m.data.name == "main")
|
||||
.unwrap_or(module_holders.borrow().first().unwrap())
|
||||
.clone();
|
||||
|
||||
let main_module_ref = main_module.compile(&context, &self.builder);
|
||||
dbg!("main");
|
||||
|
||||
for holder in module_holders.borrow().iter() {
|
||||
if holder.value == main_module.value {
|
||||
continue;
|
||||
}
|
||||
dbg!(holder.value);
|
||||
let module_ref = holder.compile(&context, &self.builder);
|
||||
LLVMLinkModules2(main_module_ref, module_ref);
|
||||
}
|
||||
|
||||
LLVMDisposeBuilder(context.builder_ref);
|
||||
LLVMContextDispose(context.context_ref);
|
||||
CompiledModule {
|
||||
module_ref: main_module_ref,
|
||||
_context: context,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -77,7 +176,7 @@ pub struct LLVMValue {
|
||||
}
|
||||
|
||||
impl ModuleHolder {
|
||||
fn compile(&self, context: &LLVMContext, builder: &Builder) {
|
||||
fn compile(&self, context: &LLVMContext, builder: &Builder) -> LLVMModuleRef {
|
||||
unsafe {
|
||||
let module_ref = LLVMModuleCreateWithNameInContext(
|
||||
into_cstring(&self.data.name).as_ptr(),
|
||||
@ -109,64 +208,7 @@ impl ModuleHolder {
|
||||
function.compile(&mut module);
|
||||
}
|
||||
|
||||
LLVM_InitializeAllTargets();
|
||||
LLVM_InitializeAllTargetInfos();
|
||||
LLVM_InitializeAllTargetMCs();
|
||||
LLVM_InitializeAllAsmParsers();
|
||||
LLVM_InitializeAllAsmPrinters();
|
||||
|
||||
let triple = LLVMGetDefaultTargetTriple();
|
||||
|
||||
let mut target: _ = null_mut();
|
||||
let mut err = ErrorMessageHolder::null();
|
||||
LLVMGetTargetFromTriple(triple, &mut target, err.borrow_mut());
|
||||
println!("{:?}, {:?}", from_cstring(triple), target);
|
||||
err.into_result().unwrap();
|
||||
|
||||
let target_machine = LLVMCreateTargetMachine(
|
||||
target,
|
||||
triple,
|
||||
c"generic".as_ptr(),
|
||||
c"".as_ptr(),
|
||||
llvm_sys::target_machine::LLVMCodeGenOptLevel::LLVMCodeGenLevelNone,
|
||||
llvm_sys::target_machine::LLVMRelocMode::LLVMRelocDefault,
|
||||
llvm_sys::target_machine::LLVMCodeModel::LLVMCodeModelDefault,
|
||||
);
|
||||
|
||||
let data_layout = LLVMCreateTargetDataLayout(target_machine);
|
||||
LLVMSetTarget(module_ref, triple);
|
||||
LLVMSetModuleDataLayout(module_ref, data_layout);
|
||||
|
||||
let mut err = ErrorMessageHolder::null();
|
||||
LLVMVerifyModule(
|
||||
module_ref,
|
||||
llvm_sys::analysis::LLVMVerifierFailureAction::LLVMPrintMessageAction,
|
||||
err.borrow_mut(),
|
||||
);
|
||||
err.into_result().unwrap();
|
||||
|
||||
let mut err = ErrorMessageHolder::null();
|
||||
LLVMTargetMachineEmitToFile(
|
||||
target_machine,
|
||||
module_ref,
|
||||
CString::new("hello.asm").unwrap().into_raw(),
|
||||
LLVMCodeGenFileType::LLVMAssemblyFile,
|
||||
err.borrow_mut(),
|
||||
);
|
||||
err.into_result().unwrap();
|
||||
|
||||
let mut err = ErrorMessageHolder::null();
|
||||
LLVMTargetMachineEmitToFile(
|
||||
target_machine,
|
||||
module_ref,
|
||||
CString::new("hello.o").unwrap().into_raw(),
|
||||
LLVMCodeGenFileType::LLVMObjectFile,
|
||||
err.borrow_mut(),
|
||||
);
|
||||
err.into_result().unwrap();
|
||||
|
||||
let module_str = from_cstring(LLVMPrintModuleToString(module_ref));
|
||||
println!("{}", module_str.unwrap());
|
||||
module_ref
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,9 @@
|
||||
//! Debug implementations for relevant types
|
||||
|
||||
use std::fmt::{Debug, Write};
|
||||
use std::{
|
||||
fmt::{Debug, Write},
|
||||
marker::PhantomData,
|
||||
};
|
||||
|
||||
use crate::{CmpPredicate, Instr, InstructionData, TerminatorKind, builder::*};
|
||||
|
||||
@ -11,6 +14,17 @@ impl Debug for Builder {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct PrintableModule<'ctx> {
|
||||
pub phantom: PhantomData<&'ctx ()>,
|
||||
pub module: ModuleHolder,
|
||||
}
|
||||
|
||||
impl<'ctx> Debug for PrintableModule<'ctx> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
self.module.fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
impl Debug for ModuleHolder {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.debug_tuple(&format!("{}({:#?}) ", self.data.name, self.value))
|
||||
|
@ -2,9 +2,10 @@
|
||||
//! Low-Level IR (LLIR) using [`Context`] and [`Builder`]. This Builder can then
|
||||
//! be used at the end to compile said LLIR into LLVM IR.
|
||||
|
||||
use std::marker::PhantomData;
|
||||
use std::{fmt::Debug, marker::PhantomData};
|
||||
|
||||
use builder::{BlockValue, Builder, FunctionValue, InstructionValue, ModuleValue};
|
||||
use builder::{BlockValue, Builder, FunctionValue, InstructionValue, ModuleHolder, ModuleValue};
|
||||
use debug::PrintableModule;
|
||||
|
||||
pub mod builder;
|
||||
pub mod compile;
|
||||
@ -76,6 +77,13 @@ impl<'ctx> Module<'ctx> {
|
||||
pub fn value(&self) -> ModuleValue {
|
||||
self.value
|
||||
}
|
||||
|
||||
pub fn as_printable(&self) -> PrintableModule<'ctx> {
|
||||
PrintableModule {
|
||||
phantom: PhantomData,
|
||||
module: self.builder.find_module(self.value),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Hash)]
|
||||
|
@ -1,8 +1,8 @@
|
||||
use std::{collections::HashMap, mem};
|
||||
|
||||
use reid_lib::{
|
||||
builder::InstructionValue, Block, CmpPredicate, ConstValue, Context, Function, FunctionFlags,
|
||||
Instr, Module, TerminatorKind as Term, Type,
|
||||
builder::InstructionValue, compile::CompiledModule, Block, CmpPredicate, ConstValue, Context,
|
||||
Function, FunctionFlags, Instr, Module, TerminatorKind as Term, Type,
|
||||
};
|
||||
|
||||
use crate::mir::{self, types::ReturnType, IndexedVariableReference, NamedVariableRef, TypeKind};
|
||||
@ -11,16 +11,14 @@ use crate::mir::{self, types::ReturnType, IndexedVariableReference, NamedVariabl
|
||||
/// LLIR that can then be finally compiled into LLVM IR.
|
||||
#[derive(Debug)]
|
||||
pub struct CodegenContext<'ctx> {
|
||||
modules: Vec<ModuleCodegen<'ctx>>,
|
||||
context: &'ctx Context,
|
||||
}
|
||||
|
||||
impl<'ctx> CodegenContext<'ctx> {
|
||||
/// Compile contained LLIR into LLVM IR and produce `hello.o` and
|
||||
/// `hello.asm`
|
||||
pub fn compile(&self) {
|
||||
for module in &self.modules {
|
||||
module.context.compile();
|
||||
}
|
||||
pub fn compile(&self) -> CompiledModule {
|
||||
self.context.compile()
|
||||
}
|
||||
}
|
||||
|
||||
@ -31,18 +29,17 @@ impl mir::Context {
|
||||
for module in &self.modules {
|
||||
modules.push(module.codegen(context));
|
||||
}
|
||||
CodegenContext { modules }
|
||||
CodegenContext { context }
|
||||
}
|
||||
}
|
||||
|
||||
struct ModuleCodegen<'ctx> {
|
||||
pub context: &'ctx Context,
|
||||
_module: Module<'ctx>,
|
||||
module: Module<'ctx>,
|
||||
}
|
||||
|
||||
impl<'ctx> std::fmt::Debug for ModuleCodegen<'ctx> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
self.context.fmt(f)
|
||||
std::fmt::Debug::fmt(&self.module.as_printable(), f)
|
||||
}
|
||||
}
|
||||
|
||||
@ -121,10 +118,7 @@ impl mir::Module {
|
||||
}
|
||||
}
|
||||
|
||||
ModuleCodegen {
|
||||
context,
|
||||
_module: module,
|
||||
}
|
||||
ModuleCodegen { module }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -134,7 +134,8 @@ pub fn compile(source: &str, path: PathBuf) -> Result<String, ReidError> {
|
||||
let codegen_modules = mir_context.codegen(&mut context);
|
||||
|
||||
dbg!(&codegen_modules);
|
||||
codegen_modules.compile();
|
||||
let compiled = codegen_modules.compile();
|
||||
compiled.output();
|
||||
|
||||
Ok(String::new())
|
||||
}
|
||||
|
@ -5,6 +5,3 @@ pub fn print(message: string) {
|
||||
puts(message);
|
||||
}
|
||||
|
||||
fn main() -> u16 {
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user