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>>> {
|
pub(crate) fn get_modules(&self) -> Rc<RefCell<Vec<ModuleHolder>>> {
|
||||||
self.modules.clone()
|
self.modules.clone()
|
||||||
}
|
}
|
||||||
|
@ -2,12 +2,13 @@
|
|||||||
//! LLIR ([`Context`]) into LLVM IR. This module is the only one that interfaces
|
//! LLIR ([`Context`]) into LLVM IR. This module is the only one that interfaces
|
||||||
//! with the LLVM API.
|
//! 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::{
|
use llvm_sys::{
|
||||||
LLVMIntPredicate, LLVMLinkage,
|
LLVMIntPredicate, LLVMLinkage,
|
||||||
analysis::LLVMVerifyModule,
|
analysis::LLVMVerifyModule,
|
||||||
core::*,
|
core::*,
|
||||||
|
linker::LLVMLinkModules2,
|
||||||
prelude::*,
|
prelude::*,
|
||||||
target::{
|
target::{
|
||||||
LLVM_InitializeAllAsmParsers, LLVM_InitializeAllAsmPrinters, LLVM_InitializeAllTargetInfos,
|
LLVM_InitializeAllAsmParsers, LLVM_InitializeAllAsmPrinters, LLVM_InitializeAllTargetInfos,
|
||||||
@ -34,8 +35,87 @@ pub struct LLVMContext {
|
|||||||
builder_ref: LLVMBuilderRef,
|
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 {
|
impl Context {
|
||||||
pub fn compile(&self) {
|
pub fn compile(&self) -> CompiledModule {
|
||||||
unsafe {
|
unsafe {
|
||||||
let context_ref = LLVMContextCreate();
|
let context_ref = LLVMContextCreate();
|
||||||
|
|
||||||
@ -44,12 +124,31 @@ impl Context {
|
|||||||
builder_ref: LLVMCreateBuilderInContext(context_ref),
|
builder_ref: LLVMCreateBuilderInContext(context_ref),
|
||||||
};
|
};
|
||||||
|
|
||||||
for holder in self.builder.get_modules().borrow().iter() {
|
let module_holders = self.builder.get_modules();
|
||||||
holder.compile(&context, &self.builder);
|
|
||||||
|
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);
|
CompiledModule {
|
||||||
LLVMContextDispose(context.context_ref);
|
module_ref: main_module_ref,
|
||||||
|
_context: context,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -77,7 +176,7 @@ pub struct LLVMValue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl ModuleHolder {
|
impl ModuleHolder {
|
||||||
fn compile(&self, context: &LLVMContext, builder: &Builder) {
|
fn compile(&self, context: &LLVMContext, builder: &Builder) -> LLVMModuleRef {
|
||||||
unsafe {
|
unsafe {
|
||||||
let module_ref = LLVMModuleCreateWithNameInContext(
|
let module_ref = LLVMModuleCreateWithNameInContext(
|
||||||
into_cstring(&self.data.name).as_ptr(),
|
into_cstring(&self.data.name).as_ptr(),
|
||||||
@ -109,64 +208,7 @@ impl ModuleHolder {
|
|||||||
function.compile(&mut module);
|
function.compile(&mut module);
|
||||||
}
|
}
|
||||||
|
|
||||||
LLVM_InitializeAllTargets();
|
module_ref
|
||||||
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());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
//! Debug implementations for relevant types
|
//! Debug implementations for relevant types
|
||||||
|
|
||||||
use std::fmt::{Debug, Write};
|
use std::{
|
||||||
|
fmt::{Debug, Write},
|
||||||
|
marker::PhantomData,
|
||||||
|
};
|
||||||
|
|
||||||
use crate::{CmpPredicate, Instr, InstructionData, TerminatorKind, builder::*};
|
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 {
|
impl Debug for ModuleHolder {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
f.debug_tuple(&format!("{}({:#?}) ", self.data.name, self.value))
|
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
|
//! Low-Level IR (LLIR) using [`Context`] and [`Builder`]. This Builder can then
|
||||||
//! be used at the end to compile said LLIR into LLVM IR.
|
//! 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 builder;
|
||||||
pub mod compile;
|
pub mod compile;
|
||||||
@ -76,6 +77,13 @@ impl<'ctx> Module<'ctx> {
|
|||||||
pub fn value(&self) -> ModuleValue {
|
pub fn value(&self) -> ModuleValue {
|
||||||
self.value
|
self.value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn as_printable(&self) -> PrintableModule<'ctx> {
|
||||||
|
PrintableModule {
|
||||||
|
phantom: PhantomData,
|
||||||
|
module: self.builder.find_module(self.value),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Hash)]
|
#[derive(Debug, Clone, Hash)]
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
use std::{collections::HashMap, mem};
|
use std::{collections::HashMap, mem};
|
||||||
|
|
||||||
use reid_lib::{
|
use reid_lib::{
|
||||||
builder::InstructionValue, Block, CmpPredicate, ConstValue, Context, Function, FunctionFlags,
|
builder::InstructionValue, compile::CompiledModule, Block, CmpPredicate, ConstValue, Context,
|
||||||
Instr, Module, TerminatorKind as Term, Type,
|
Function, FunctionFlags, Instr, Module, TerminatorKind as Term, Type,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::mir::{self, types::ReturnType, IndexedVariableReference, NamedVariableRef, TypeKind};
|
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.
|
/// LLIR that can then be finally compiled into LLVM IR.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct CodegenContext<'ctx> {
|
pub struct CodegenContext<'ctx> {
|
||||||
modules: Vec<ModuleCodegen<'ctx>>,
|
context: &'ctx Context,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'ctx> CodegenContext<'ctx> {
|
impl<'ctx> CodegenContext<'ctx> {
|
||||||
/// Compile contained LLIR into LLVM IR and produce `hello.o` and
|
/// Compile contained LLIR into LLVM IR and produce `hello.o` and
|
||||||
/// `hello.asm`
|
/// `hello.asm`
|
||||||
pub fn compile(&self) {
|
pub fn compile(&self) -> CompiledModule {
|
||||||
for module in &self.modules {
|
self.context.compile()
|
||||||
module.context.compile();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -31,18 +29,17 @@ impl mir::Context {
|
|||||||
for module in &self.modules {
|
for module in &self.modules {
|
||||||
modules.push(module.codegen(context));
|
modules.push(module.codegen(context));
|
||||||
}
|
}
|
||||||
CodegenContext { modules }
|
CodegenContext { context }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ModuleCodegen<'ctx> {
|
struct ModuleCodegen<'ctx> {
|
||||||
pub context: &'ctx Context,
|
module: Module<'ctx>,
|
||||||
_module: Module<'ctx>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'ctx> std::fmt::Debug for ModuleCodegen<'ctx> {
|
impl<'ctx> std::fmt::Debug for ModuleCodegen<'ctx> {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
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 {
|
ModuleCodegen { module }
|
||||||
context,
|
|
||||||
_module: module,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,7 +134,8 @@ pub fn compile(source: &str, path: PathBuf) -> Result<String, ReidError> {
|
|||||||
let codegen_modules = mir_context.codegen(&mut context);
|
let codegen_modules = mir_context.codegen(&mut context);
|
||||||
|
|
||||||
dbg!(&codegen_modules);
|
dbg!(&codegen_modules);
|
||||||
codegen_modules.compile();
|
let compiled = codegen_modules.compile();
|
||||||
|
compiled.output();
|
||||||
|
|
||||||
Ok(String::new())
|
Ok(String::new())
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,3 @@ pub fn print(message: string) {
|
|||||||
puts(message);
|
puts(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() -> u16 {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
Loading…
Reference in New Issue
Block a user