Skip to content

Commit

Permalink
Better optimizations
Browse files Browse the repository at this point in the history
  • Loading branch information
FractalFir committed Sep 8, 2024
1 parent cb07f7d commit a05c130
Show file tree
Hide file tree
Showing 14 changed files with 369 additions and 48 deletions.
19 changes: 17 additions & 2 deletions cilly/src/bin/linker/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,22 @@ fn main() {
// Load assemblies from files

let (mut final_assembly, _) = load::load_assemblies(to_link.as_slice(), ar_to_link.as_slice());

/*
{
let msg = final_assembly.alloc_string("Starting constant initialization");
let msg = final_assembly.alloc_node(Const::PlatformString(msg));
let console = ClassRef::console(&mut final_assembly);
let fn_name = final_assembly.alloc_string("WriteLine");
let mref = final_assembly.class_ref(console).clone().static_mref(
&[Type::PlatformString],
Type::Void,
fn_name,
&mut final_assembly,
);
let stat = final_assembly.alloc_root(CILRoot::Call(Box::new((mref, [msg].into()))));
final_assembly.add_cctor(&[stat]);
}
*/
let path: std::path::PathBuf = output_file_path.into();

let is_lib = output_file_path.contains(".dll")
Expand Down Expand Up @@ -357,7 +372,7 @@ fn main() {
cilly::v2::builtins::instert_threading(&mut final_assembly, &mut overrides);
cilly::v2::builtins::insert_swap_at_generic(&mut final_assembly, &mut overrides);
cilly::v2::builtins::insert_bounds_check(&mut final_assembly, &mut overrides);

cilly::v2::builtins::math::math(&mut final_assembly, &mut overrides);
// Ensure the cctor and tcctor exist!
let _ = final_assembly.tcctor();
let _ = final_assembly.cctor();
Expand Down
4 changes: 2 additions & 2 deletions cilly/src/v2/asm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ impl Assembly {
pub fn methods_with<'a>(
&'a self,
mut filter: impl FnMut(&Self, MethodDefIdx, &MethodDef) -> bool + 'a,
) -> impl Iterator<Item = (&MethodDefIdx, &MethodDef)> + 'a {
) -> impl Iterator<Item = (&'a MethodDefIdx, &'a MethodDef)> + 'a {
self.method_defs
.iter()
.filter(move |(id, def)| filter(self, **id, def))
Expand Down Expand Up @@ -141,7 +141,7 @@ impl Assembly {
pub fn find_strs_containing<'a, P: std::str::pattern::Pattern + Clone + 'a>(
&'a self,
pat: P,
) -> impl Iterator<Item = StringIdx> + '_ {
) -> impl Iterator<Item = StringIdx> + 'a {
self.strings
.0
.iter()
Expand Down
12 changes: 12 additions & 0 deletions cilly/src/v2/asm_link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -429,6 +429,18 @@ impl Assembly {
let tpe = self.translate_type(source, *tpe);
CILRoot::StInd(Box::new((addr, val, tpe, *volitile)))
}
CILRoot::CpObj { src, dst, tpe } => {
let src = self.translate_node(source, source.get_node(src).clone());
let src = self.alloc_node(src);
let dst = self.translate_node(source, source.get_node(dst).clone());
let dst = self.alloc_node(dst);
let tpe = self.translate_type(source, *source.get_type(tpe));
CILRoot::CpObj {
src,
dst,
tpe: self.alloc_type(tpe),
}
}
CILRoot::InitBlk(info) => {
let (dst, val, count) = info.as_ref();
let dst = self.translate_node(source, source.get_node(*dst).clone());
Expand Down
68 changes: 67 additions & 1 deletion cilly/src/v2/builtins/math.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
use crate::v2::{cilnode::MethodKind, Assembly, CILNode, ClassRef, Int, MethodRef, NodeIdx, Type};
use crate::v2::{
asm::MissingMethodPatcher,
cilnode::MethodKind,
hashable::{HashableF32, HashableF64},
Assembly, BasicBlock, BinOp, CILNode, CILRoot, ClassRef, Const, Float, Int, MethodImpl,
MethodRef, NodeIdx, Type,
};

pub fn int_max(asm: &mut Assembly, lhs: NodeIdx, rhs: NodeIdx, int: Int) -> NodeIdx {
let math = ClassRef::math(asm);
Expand Down Expand Up @@ -27,3 +33,63 @@ pub fn int_min(asm: &mut Assembly, lhs: NodeIdx, rhs: NodeIdx, int: Int) -> Node
));
asm.alloc_node(CILNode::Call(Box::new((mref, Box::new([lhs, rhs])))))
}
pub fn ldexpf(asm: &mut Assembly, patcher: &mut MissingMethodPatcher) {
let name = asm.alloc_string("ldexpf");
let generator = move |_, asm: &mut Assembly| {
let arg = asm.alloc_node(CILNode::LdArg(0));
let exp = asm.alloc_node(CILNode::LdArg(1));
let exp = asm.alloc_node(CILNode::FloatCast {
input: exp,
target: Float::F32,
is_signed: true,
});
let two = asm.alloc_node(Const::F32(HashableF32(2.0)));
let pow = Float::F32.pow(two, exp, asm);
let res_val = asm.alloc_node(CILNode::BinOp(arg, pow, BinOp::Mul));
let ret = asm.alloc_root(CILRoot::Ret(res_val));
MethodImpl::MethodBody {
blocks: vec![BasicBlock::new(vec![ret], 0, None)],
locals: vec![],
}
};
patcher.insert(name, Box::new(generator));
}
pub fn ldexp(asm: &mut Assembly, patcher: &mut MissingMethodPatcher) {
let name = asm.alloc_string("ldexp");
let generator = move |_, asm: &mut Assembly| {
let arg = asm.alloc_node(CILNode::LdArg(0));
let exp = asm.alloc_node(CILNode::LdArg(1));
let exp = asm.alloc_node(CILNode::FloatCast {
input: exp,
target: Float::F64,
is_signed: true,
});
let two = asm.alloc_node(Const::F64(HashableF64(2.0)));
let pow = Float::F64.pow(two, exp, asm);
let res_val = asm.alloc_node(CILNode::BinOp(arg, pow, BinOp::Mul));
let ret = asm.alloc_root(CILRoot::Ret(res_val));
MethodImpl::MethodBody {
blocks: vec![BasicBlock::new(vec![ret], 0, None)],
locals: vec![],
}
};
patcher.insert(name, Box::new(generator));
}
/*
pub fn bitreverse_u128(asm: &mut Assembly, patcher: &mut MissingMethodPatcher) {
let name = asm.alloc_string("bitreverse_u128");
let generator = move |_, asm: &mut Assembly| {
let arg = asm.alloc_node(CILNode::LdArg(0));
let loc0 = asm.alloc_node(CILNode::LdLoc(0));
let ret = asm.alloc_root(CILRoot::Ret(res_val));
MethodImpl::MethodBody {
blocks: vec![BasicBlock::new(vec![ret], 0, None)],
locals: vec![(None, asm.alloc_type(Type::Int(Int::I128)))],
}
};
patcher.insert(name, Box::new(generator));
} */
pub fn math(asm: &mut Assembly, patcher: &mut MissingMethodPatcher) {
ldexp(asm, patcher);
ldexpf(asm, patcher);
}
56 changes: 38 additions & 18 deletions cilly/src/v2/builtins/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use super::{
asm::MissingMethodPatcher, cilnode::MethodKind, Access, Assembly, BasicBlock, CILNode, CILRoot,
ClassDef, ClassRef, Const, FieldDesc, Int, MethodDef, MethodImpl, MethodRef, Type,
asm::MissingMethodPatcher, cilnode::MethodKind, cilroot::BranchCond, Access, Assembly,
BasicBlock, CILNode, CILRoot, ClassDef, ClassRef, Const, FieldDesc, Int, MethodDef, MethodImpl,
MethodRef, Type,
};

pub mod atomics;
Expand Down Expand Up @@ -159,6 +160,7 @@ pub fn insert_heap(asm: &mut Assembly, patcher: &mut MissingMethodPatcher) {
insert_rust_realloc(asm, patcher);
insert_rust_dealloc(asm, patcher);
insert_catch_unwind(asm, patcher);
insert_pause(asm, patcher);
let rust_exception = asm.alloc_string("RustException");
let data_pointer = asm.alloc_string("data_pointer");
let this = asm.alloc_string("this");
Expand Down Expand Up @@ -200,6 +202,18 @@ pub fn insert_heap(asm: &mut Assembly, patcher: &mut MissingMethodPatcher) {
vec![Some(this), Some(data_pointer)],
));
}

fn insert_pause(asm: &mut Assembly, patcher: &mut MissingMethodPatcher) {
let name = asm.alloc_string("llvm.x86.sse2.pause");
let generator = move |_, asm: &mut Assembly| {
let ret = asm.alloc_root(CILRoot::VoidRet);
MethodImpl::MethodBody {
blocks: vec![BasicBlock::new(vec![ret], 0, None)],
locals: vec![],
}
};
patcher.insert(name, Box::new(generator));
}
fn insert_catch_unwind(asm: &mut Assembly, patcher: &mut MissingMethodPatcher) {
let name = asm.alloc_string("catch_unwind");
let generator = move |_, asm: &mut Assembly| {
Expand Down Expand Up @@ -233,6 +247,14 @@ fn insert_catch_unwind(asm: &mut Assembly, patcher: &mut MissingMethodPatcher) {
asm.alloc_class_ref(ClassRef::new(rust_exception, None, false, [].into()));
let rust_exception_tpe = Type::ClassRef(rust_exception);
let rust_exception_tpe = asm.alloc_type(rust_exception_tpe);
// Check if exception is the right type, otherwise jump away
let check_exception_tpe = asm.alloc_node(CILNode::IsInst(ldloc_1, rust_exception_tpe));
let rethrow_if_wrong_exception = asm.alloc_root(CILRoot::Branch(Box::new((
0,
4,
Some(BranchCond::False(check_exception_tpe)),
))));
// Cast the excpetion
let cast_exception = asm.alloc_node(CILNode::CheckedCast(ldloc_1, rust_exception_tpe));
let data_pointer = asm.alloc_string("data_pointer");
let ptr_field = asm.alloc_field(FieldDesc::new(
Expand All @@ -253,27 +275,25 @@ fn insert_catch_unwind(asm: &mut Assembly, patcher: &mut MissingMethodPatcher) {
let const_1 = asm.alloc_node(Const::I32(1));
let ret_0 = asm.alloc_root(CILRoot::Ret(const_0));
let ret_1 = asm.alloc_root(CILRoot::Ret(const_1));
// Debug
let console = ClassRef::console(asm);
let write_line = asm.alloc_string("WriteLine");
let write_line = asm.class_ref(console).clone().static_mref(
&[Type::PlatformObject],
Type::Void,
write_line,
asm,
);
let print_exception =
asm.alloc_root(CILRoot::Call(Box::new((write_line, Box::new([ldloc_1])))));
let rethrow = asm.alloc_root(CILRoot::ReThrow);
MethodImpl::MethodBody {
blocks: vec![
BasicBlock::new(
vec![calli_try, exit_try_success],
0,
Some(vec![BasicBlock::new(
vec![set_exception, calli_catch, exit_try_faliure],
1,
None,
)]),
Some(vec![
BasicBlock::new(
vec![
set_exception,
rethrow_if_wrong_exception,
calli_catch,
exit_try_faliure,
],
1,
None,
),
BasicBlock::new(vec![rethrow], 4, None),
]),
),
BasicBlock::new(vec![ret_0], 2, None),
BasicBlock::new(vec![ret_1], 3, None),
Expand Down
18 changes: 17 additions & 1 deletion cilly/src/v2/cilroot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use super::{
cilnode::MethodKind,
field::FieldIdx,
Assembly, CILNode, FieldDesc, Float, FnSig, Int, MethodRef, MethodRefIdx, NodeIdx, SigIdx,
StaticFieldDesc, StaticFieldIdx, StringIdx, Type,
StaticFieldDesc, StaticFieldIdx, StringIdx, Type, TypeIdx,
};
use crate::cil_root::CILRoot as V1Root;
//use crate::cil_node::CILNode as V1Node;
Expand Down Expand Up @@ -51,6 +51,11 @@ pub enum CILRoot {
field: StaticFieldIdx,
val: NodeIdx,
},
CpObj {
src: NodeIdx,
dst: NodeIdx,
tpe: TypeIdx,
},
}

#[derive(Hash, PartialEq, Eq, Clone, Debug, Serialize, Deserialize)]
Expand Down Expand Up @@ -130,6 +135,7 @@ impl CILRoot {
args.push(ptr);
args.into()
}
CILRoot::CpObj { src, dst, tpe } => [src, dst].into(),
}
}
#[allow(clippy::too_many_lines)]
Expand Down Expand Up @@ -552,6 +558,16 @@ impl CILRoot {
)));
root_map(root, asm)
}
CILRoot::CpObj { src, dst, tpe } => {
let src = asm.get_node(src).clone().map(asm, node_map);
let dst = asm.get_node(dst).clone().map(asm, node_map);
let root = CILRoot::CpObj {
src: asm.alloc_node(src),
dst: asm.alloc_node(dst),
tpe,
};
root_map(root, asm)
}
CILRoot::InitBlk(blk) => {
let (dst, val, count) = *blk;
let dst = asm.get_node(dst).clone().map(asm, node_map);
Expand Down
14 changes: 14 additions & 0 deletions cilly/src/v2/float.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,20 @@ impl Float {
Float::F128 => todo!(),
}
}
/// Raises base to power.
pub fn pow(&self, base: NodeIdx, exp: NodeIdx, asm: &mut Assembly) -> NodeIdx {
let pow = asm.alloc_string("Pow");
let class = self.class(asm);
let sig = asm.sig([Type::Float(*self), Type::Float(*self)], *self);
let mref = asm.alloc_methodref(MethodRef::new(
class,
pow,
sig,
MethodKind::Static,
[].into(),
));
asm.alloc_node(CILNode::Call(Box::new((mref, Box::new([base, exp])))))
}
}
impl From<Float> for Type {
fn from(value: Float) -> Self {
Expand Down
6 changes: 6 additions & 0 deletions cilly/src/v2/il_exporter/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -951,6 +951,12 @@ impl ILExporter {
call.0
)
}
super::CILRoot::CpObj { src, dst, tpe } => {
self.export_node(asm, out, *src)?;
self.export_node(asm, out, *dst)?;
let tpe = type_il(asm.get_type(*tpe), asm);
writeln!(out, "cpobj {tpe}")
}
super::CILRoot::StInd(stind) => {
self.export_node(asm, out, stind.0)?;
self.export_node(asm, out, stind.1)?;
Expand Down
21 changes: 21 additions & 0 deletions cilly/src/v2/iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,24 @@ impl<'asm> Iterator for CILIter<'asm> {
continue;
}
},
CILIterElem::Root(CILRoot::CpObj { src, dst, tpe }) => match idx {
1 => {
*idx += 1;
let lhs = self.asm.get_node(*src);
self.elems.push((CILIterElem::Node(lhs.clone()), 0));
continue;
}
2 => {
*idx += 1;
let rhs = self.asm.get_node(*dst);
self.elems.push((CILIterElem::Node(rhs.clone()), 0));
continue;
}
_ => {
self.elems.pop();
continue;
}
},
CILIterElem::Node(
CILNode::BinOp(lhs, rhs, _)
| CILNode::LdElelemRef {
Expand Down Expand Up @@ -511,6 +529,9 @@ impl<'this, T: Iterator<Item = CILIterElem> + 'this> TpeIter<'this> for T {
let tpe = field.tpe();
Some(Box::new([class, tpe].into_iter()))
}
CILRoot::CpObj { tpe, .. } => {
Some(Box::new(std::iter::once(*asm.get_type(tpe))))
}
// Since this method is called, then if it uses an "internal" type, we must assume it is defined in this module. Thus, its types are already included, and we don't need to include them again.
CILRoot::Call(_) | CILRoot::CallI(_) => None,
CILRoot::StInd(info) => Some(Box::new(std::iter::once(info.2))),
Expand Down
3 changes: 3 additions & 0 deletions cilly/src/v2/method.rs
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,9 @@ impl MethodDef {
arg_debug_count,
v1.call_site().name()
);
for arg in &arg_names {
println!("{:?}", arg.map(|arg| asm.get_string(arg)));
}
arg_names.truncate(arg_sig_count);
}
}
Expand Down
Loading

0 comments on commit a05c130

Please sign in to comment.