Skip to content

Commit

Permalink
Merge branch 'main' into execution-target
Browse files Browse the repository at this point in the history
  • Loading branch information
JonasWanke committed Oct 12, 2023
2 parents ede20a4 + 472fc9e commit fbaa343
Show file tree
Hide file tree
Showing 2 changed files with 97 additions and 59 deletions.
142 changes: 88 additions & 54 deletions compiler/backend_inkwell/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ use inkwell::{
context::Context,
module::Module,
support::LLVMString,
targets::{InitializationConfig, Target, TargetMachine},
types::{
BasicMetadataTypeEnum, BasicType, FunctionType, IntType, PointerType, StructType, VoidType,
},
Expand All @@ -29,7 +30,7 @@ use llvm_sys as _;
use rustc_hash::FxHashMap;
use std::{
collections::{HashMap, HashSet},
path::PathBuf,
path::Path,
sync::Arc,
};

Expand All @@ -44,8 +45,9 @@ fn llvm_ir(db: &dyn LlvmIrDb, target: ExecutionTarget) -> Result<RichIr, ModuleE
let (mir, _, _) = db.optimized_mir(target, TracingConfig::off())?;

let context = Context::create();
let mut codegen = CodeGen::new(&context, "module", mir);
let llvm_ir = codegen.compile("", false, true).unwrap();
let codegen = CodeGen::new(&context, "module", mir);
let module = codegen.compile(false, true).unwrap();
let llvm_ir = module.module.print_to_string();

Ok(llvm_ir.to_str().unwrap().to_rich_ir(true))
}
Expand All @@ -70,6 +72,84 @@ pub struct CodeGen<'ctx> {
unrepresented_ids: HashSet<Id>,
}

pub struct LlvmCandyModule<'ctx> {
module: Module<'ctx>,
}

impl<'ctx> LlvmCandyModule<'ctx> {
pub fn compile_obj_and_link(
&self,
path: &str,
build_rt: bool,
debug: bool,
linker: &str,
) -> Result<(), std::io::Error> {
if build_rt {
std::process::Command::new("make")
.args(["-C", "compiler/backend_inkwell/candy_runtime/", "clean"])
.spawn()?
.wait()?;

std::process::Command::new("make")
.args([
"-C",
"compiler/backend_inkwell/candy_runtime/",
"candy_runtime.a",
])
.spawn()?
.wait()?;
}
let triple = TargetMachine::get_default_triple();
Target::initialize_native(&InitializationConfig::default()).unwrap();
let target = Target::from_triple(&triple).unwrap();

let target_machine = target
.create_target_machine(
&triple,
"generic",
"",
inkwell::OptimizationLevel::Default,
inkwell::targets::RelocMode::Default,
inkwell::targets::CodeModel::Default,
)
.unwrap();

self.module
.set_data_layout(&target_machine.get_target_data().get_data_layout());
self.module.set_triple(&triple);

let o_path = format!("{path}.o");

target_machine
.write_to_file(
&self.module,
inkwell::targets::FileType::Object,
Path::new(&o_path),
)
.unwrap();

std::process::Command::new(linker)
.args([
"-dynamic-linker",
// TODO: This is not portable.
"/lib/ld-linux-x86-64.so.2",
"/usr/lib/crt1.o",
"/usr/lib/crti.o",
"-L/usr/lib",
"-lc",
&o_path,
"compiler/backend_inkwell/candy_runtime/candy_runtime.a",
"/usr/lib/crtn.o",
if debug { "-g" } else { "" },
"-o",
o_path.as_str().strip_suffix(".candy.o").unwrap(),
])
.spawn()?
.wait()?;
Ok(())
}
}

impl<'ctx> CodeGen<'ctx> {
pub fn new(context: &'ctx Context, module_name: &str, mir: Arc<Mir>) -> Self {
let module = context.create_module(module_name);
Expand All @@ -93,11 +173,10 @@ impl<'ctx> CodeGen<'ctx> {
}

pub fn compile(
&mut self,
path: &str,
mut self,
print_llvm_ir: bool,
print_main_output: bool,
) -> Result<LLVMString, LLVMString> {
) -> Result<LlvmCandyModule<'ctx>, LLVMString> {
let void_type = self.context.void_type();
let i8_type = self.context.i8_type();
let i32_type = self.context.i32_type();
Expand Down Expand Up @@ -234,54 +313,9 @@ impl<'ctx> CodeGen<'ctx> {
self.module.print_to_stderr();
}
self.module.verify()?;
if !path.is_empty() {
let bc_path = PathBuf::from(format!("{path}.bc"));
self.module.write_bitcode_to_path(&bc_path);
}
Ok(self.module.print_to_string())
}

pub fn compile_asm_and_link(
&self,
path: &str,
build_rt: bool,
debug: bool,
) -> Result<(), std::io::Error> {
let bc_path = PathBuf::from(&format!("{path}.bc"));
std::process::Command::new("llc")
.arg(&bc_path)
.args(["-O3"])
.spawn()?
.wait()?;
if build_rt {
std::process::Command::new("make")
.args(["-C", "compiler/backend_inkwell/candy_runtime/", "clean"])
.spawn()?
.wait()?;

std::process::Command::new("make")
.args([
"-C",
"compiler/backend_inkwell/candy_runtime/",
"candy_runtime.a",
])
.spawn()?
.wait()?;
}
let s_path = PathBuf::from(format!("{path}.s"));
std::process::Command::new("clang")
.args([
s_path.to_str().unwrap(),
"compiler/backend_inkwell/candy_runtime/candy_runtime.a",
if debug { "-g" } else { "" },
"-O3",
"-flto",
"-o",
&s_path.to_str().unwrap().replace(".candy.s", ""),
])
.spawn()?
.wait()?;
Ok(())
Ok(LlvmCandyModule {
module: self.module,
})
}

fn compile_mir(
Expand Down
14 changes: 9 additions & 5 deletions compiler/cli/src/inkwell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ pub(crate) struct Options {
#[arg(short = 'g', default_value_t = false)]
debug: bool,

/// The linker to be used. Defaults to `ld.lld`
#[arg(long, default_value = "ld.lld")]
linker: String,

/// The file or package to compile. If none is provided, compile the package
/// of your current working directory.
#[arg(value_hint = ValueHint::FilePath)]
Expand Down Expand Up @@ -89,12 +93,12 @@ pub(crate) fn compile(options: Options) -> ProgramResult {
}

let context = candy_backend_inkwell::inkwell::context::Context::create();
let mut codegen = CodeGen::new(&context, &path, mir);
codegen
.compile(&path, options.print_llvm_ir, options.print_main_output)
let codegen = CodeGen::new(&context, &path, mir);
let llvm_candy_module = codegen
.compile(options.print_llvm_ir, options.print_main_output)
.map_err(|e| Exit::LlvmError(e.to_string()))?;
codegen
.compile_asm_and_link(&path, options.build_runtime, options.debug)
llvm_candy_module
.compile_obj_and_link(&path, options.build_runtime, options.debug, &options.linker)
.map_err(|err| {
error!("Failed to compile and link executable: {}", err);
Exit::ExternalError
Expand Down

1 comment on commit fbaa343

@jwbot
Copy link
Collaborator

@jwbot jwbot commented on fbaa343 Oct 12, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Compiler

Benchmark suite Current: fbaa343 Previous: 472fc9e Ratio
Time: Compiler/hello_world 20684899 ns/iter (± 1938289) 21248274 ns/iter (± 999537) 0.97
Time: Compiler/fibonacci 171307336 ns/iter (± 970801) 184692577 ns/iter (± 5307988) 0.93
Time: VM Runtime/hello_world 47401 ns/iter (± 25790) 46402 ns/iter (± 16044) 1.02
Time: VM Runtime/fibonacci/15 274540320 ns/iter (± 1010431) 290923428 ns/iter (± 3266860) 0.94
Time: VM Runtime/PLB/binarytrees/6 1266210934 ns/iter (± 2531119) 1342814062 ns/iter (± 11057346) 0.94

This comment was automatically generated by workflow using github-action-benchmark.

Please sign in to comment.