Skip to content

Commit

Permalink
Added support for 128 bit floats. Reduced link time and linker memory…
Browse files Browse the repository at this point in the history
… usage slightly.
  • Loading branch information
FractalFir committed Aug 16, 2024
1 parent 459ab5c commit e9e46ea
Show file tree
Hide file tree
Showing 27 changed files with 915 additions and 622 deletions.
18 changes: 13 additions & 5 deletions cilly/src/bin/linker/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use cilly::{
asm::DEAD_CODE_ELIMINATION,
call_site::CallSite,
conv_usize,
libc_fns::{LIBC_FNS, LIBC_MODIFIES_ERRNO},
libc_fns::{self, LIBC_FNS, LIBC_MODIFIES_ERRNO},
v2::{
asm::{MissingMethodPatcher, ILASM_FLAVOUR},
cilnode::MethodKind,
Expand Down Expand Up @@ -175,12 +175,20 @@ fn main() {
|| output_file_path.contains(".so")
|| output_file_path.contains(".o");

let externs = LIBC_FNS
let mut externs: FxHashMap<_, _> = LIBC_FNS
.iter()
.map(|fn_name| (*fn_name, LIBC.as_ref()))
.map(|fn_name| (*fn_name, LIBC.to_string()))
.collect();

let modifies_errno = LIBC_MODIFIES_ERRNO.iter().copied().collect();
if let Some(f128_support) = libc_fns::f128_support_lib() {
let f128_support = f128_support.to_str().to_owned().unwrap();
externs.extend(
libc_fns::F128_SYMBOLS
.iter()
.map(|fn_name| (*fn_name, f128_support.to_owned())),
);
}
let mut overrides: MissingMethodPatcher = FxHashMap::default();
overrides.insert(
final_assembly.alloc_string("pthread_atfork"),
Expand Down Expand Up @@ -351,7 +359,7 @@ fn main() {
println!("Eliminating dead code");
final_assembly.eliminate_dead_code();
}
let mut fuel = final_assembly.fuel_from_env();
let mut fuel = final_assembly.fuel_from_env().scale(0.1);
final_assembly.opt(&mut fuel);
final_assembly
.save_tmp(&mut std::fs::File::create(path.with_extension("cilly2")).unwrap())
Expand Down Expand Up @@ -443,7 +451,7 @@ fn bootstrap_source(fpath: &Path, output_file_path: &str, jumpstart_cmd: &str) -
IlasmFlavour::Clasic => String::new(),
IlasmFlavour::Modern => format!(
"{output_file_path}.pdb",
output_file_path = fpath.file_name().unwrap().to_string_lossy()
output_file_path = fpath.file_stem().unwrap().to_string_lossy()
),
},
native_companion_file = if *NATIVE_PASSTROUGH {
Expand Down
6 changes: 4 additions & 2 deletions cilly/src/cil_root.rs
Original file line number Diff line number Diff line change
Expand Up @@ -850,10 +850,12 @@ impl CILRoot {
))
}
};
if **inner != **tpe && !matches!(inner.as_ref(), Type::I128 | Type::U128) {
if **inner != **tpe
&& !matches!(inner.as_ref(), Type::I128 | Type::U128 | Type::F128)
{
Err(format!("Can't indirectly set a value of type {tpe:?} because the pointer points to {inner:?}, and it should point to {tpe:?}"))?;
}
if **inner != value_calc {
if **inner != value_calc && !(value_calc == Type::I128 && **inner == Type::F128) {
Err(format!("Can't indirectly set a value of type {tpe:?} because the provided value is {value_calc:?}, and it should be {inner:?}"))
} else {
Ok(())
Expand Down
1 change: 1 addition & 0 deletions cilly/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ pub fn mangle(tpe: &Type) -> std::borrow::Cow<'static, str> {
Type::F16 => "f16".into(),
Type::F32 => "f32".into(),
Type::F64 => "f64".into(),
Type::F128 => "f128".into(),
Type::Ptr(inner) => format!("p{inner}", inner = mangle(inner,)).into(),
Type::DotnetType(tpe) => {
assert!(
Expand Down
29 changes: 29 additions & 0 deletions cilly/src/libc_fns.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use std::path::PathBuf;
/// A list of all functions which are redirected to system libc.
pub const LIBC_FNS: &[&str] = &[
"__errno_location",
Expand Down Expand Up @@ -673,7 +674,35 @@ pub const LIBM_FNS: &[&str] = &[
"log1pf",
"tgamma",
"tgammaf",
"fmodl",
];
pub const F128_SYMBOLS: &[&str] = &[
"__addtf3", "__subtf3", "__multf3", "__divtf3", "__eqtf2", "__netf2", "__getf2", "__lttf2",
"__letf2", "__gttf2",
];
#[cfg(all(target_os = "linux", target_env = "gnu"))]
// TODO: this is not portable at all.
pub fn f128_support_lib() -> Option<PathBuf> {
// 1st. Open `/usr/lib/`.

let dir = std::fs::read_dir("/usr/lib64").expect("No `/usr/lib64`");
// 2nd Iterate trough all files there, and search for the GNU `libgcc_s`, where the f128 support is located.
for entry in dir {
let entry = entry.unwrap();
let name = entry.file_name();
let Some(name) = name.to_str() else {
continue;
};
if name.contains("libgcc_s") && entry.metadata().unwrap().is_file() {
return Some(entry.path());
}
}
None
}
#[cfg(not(all(target_os = "linux", target_env = "gnu")))]
pub fn f128_support() -> Option<String> {
None
}
/*
"pthread_atfork",
"pthread_attr_destroy",
Expand Down
1 change: 1 addition & 0 deletions cilly/src/type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ pub enum Type {
F16,
F32,
F64,
F128,
// Unsigned intiegers
U8,
U16,
Expand Down
8 changes: 6 additions & 2 deletions cilly/src/v2/asm.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use super::{
bimap::{calculate_hash, BiMap, BiMapIndex, IntoBiMapIndex},
cache::{CachedAssemblyInfo, NonMaxU32, StackUsage},
cilnode::{BinOp, MethodKind, UnOp},
opt::{OptFuel, SideEffectInfoCache},
Access, CILNode, CILRoot, ClassDef, ClassDefIdx, ClassRef, ClassRefIdx, Const, Exporter,
Expand Down Expand Up @@ -548,6 +547,11 @@ impl Assembly {
if let Some(cref) = self.class_ref_to_def(rust_void) {
previosly_ressurected.insert(cref);
}
let f128 = self.alloc_string("f128");
let f128 = self.alloc_class_ref(ClassRef::new(f128, None, true, vec![].into()));
if let Some(cref) = self.class_ref_to_def(f128) {
previosly_ressurected.insert(cref);
}

let mut to_resurrect: FxHashSet<ClassDefIdx> = FxHashSet::default();
let mut alive: FxHashSet<ClassDefIdx> = FxHashSet::default();
Expand Down Expand Up @@ -603,7 +607,7 @@ impl Assembly {

pub fn patch_missing_methods(
&mut self,
externs: FxHashMap<&str, &str>,
externs: FxHashMap<&str, String>,
modifies_errno: FxHashSet<&str>,
override_methods: MissingMethodPatcher,
) {
Expand Down
2 changes: 1 addition & 1 deletion cilly/src/v2/builtins/atomics.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::v2::{
asm::MissingMethodPatcher, cilnode::MethodKind, cilroot::BranchCond, BasicBlock, BinOp,
CILNode, CILRoot, ClassRef, Const, Int, MethodDef, MethodImpl, MethodRef, Type,
CILNode, CILRoot, ClassRef, Const, Int, MethodImpl, MethodRef, Type,
};

use super::{
Expand Down
20 changes: 7 additions & 13 deletions cilly/src/v2/c_exporter/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,10 @@ use super::{

pub struct CExporter {
is_lib: bool,

}
impl CExporter {
pub fn new(is_lib: bool) -> Self {
Self {
is_lib,

}
Self { is_lib }
}
fn export_class(
&self,
Expand All @@ -27,8 +23,8 @@ impl CExporter {
method_decls: &mut impl Write,
method_defs: &mut impl Write,
type_defs: &mut impl Write,
defined_types: &mut FxHashSet<ClassDefIdx> ,
delayed_defs: &mut FxHashSet<ClassDefIdx>
defined_types: &mut FxHashSet<ClassDefIdx>,
delayed_defs: &mut FxHashSet<ClassDefIdx>,
) -> std::io::Result<()> {
todo!();
}
Expand All @@ -46,11 +42,11 @@ impl CExporter {
&mut method_defs,
&mut type_defs,
&mut defined_types,
&mut delayed_defs
&mut delayed_defs,
)?;
}
while !delayed_defs.is_empty(){
/*
while !delayed_defs.is_empty() {
/*
self.export_class( asm,
*class_def,
&mut method_decls,
Expand Down Expand Up @@ -86,14 +82,12 @@ impl Exporter for CExporter {
.arg(exe_out)
.arg("-g")
.arg("-Ofast")

// .arg("-FOLD") saves up on space, consider enabling.
;
let out = cmd.output().unwrap();
let stdout = String::from_utf8_lossy(&out.stdout);
let stderr = String::from_utf8_lossy(&out.stderr);
if stderr.contains("error") || stderr.contains("fatal")
{
if stderr.contains("error") || stderr.contains("fatal") {
panic!(
"stdout:{} stderr:{} cmd:{cmd:?}",
stdout,
Expand Down
5 changes: 2 additions & 3 deletions cilly/src/v2/class.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
use std::num::NonZeroU32;

use fxhash::FxHashMap;
use serde::{Deserialize, Serialize};

use crate::{v2::MethodDef, DotnetTypeRef as V1ClassRef};

use super::{
access::Access,
bimap::{BiMapIndex, IntoBiMapIndex},
opt::{OptFuel, SideEffectInfoCache},
Assembly, MethodDefIdx, StringIdx, Type,
};

Expand Down Expand Up @@ -291,9 +289,10 @@ impl ClassDef {
}
self.methods_mut().push(ref_idx);
}
/*
/// Optimizes this class definition, consuming fuel
pub fn opt(&mut self, fuel: &mut OptFuel, asm: &mut Assembly, cache: &mut SideEffectInfoCache) {
}
} */
}
#[derive(Hash, PartialEq, Eq, Clone, Debug, Copy, Serialize, Deserialize)]
pub struct ClassDefIdx(pub ClassRefIdx);
Expand Down
1 change: 1 addition & 0 deletions cilly/src/v2/float.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ pub enum Float {
F16,
F32,
F64,
F128,
}
impl From<Float> for Type {
fn from(value: Float) -> Self {
Expand Down
Loading

0 comments on commit e9e46ea

Please sign in to comment.