Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

perf: reduce register pressure #636

Merged
merged 2 commits into from
Dec 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,5 @@ members = [
"package/origlang-source-span",
"package/origlang-typesystem-model",
"package/origlang-platform",
"package/origlang-testsuite", "package/origlang-lexer", "package/origlang-parser", "package/origlang-typecheck", "package/origlang-token-stream",
"package/origlang-testsuite", "package/origlang-lexer", "package/origlang-parser", "package/origlang-typecheck", "package/origlang-token-stream", "package/origlang-type-stringify", "package/origlang-slice-in-box",
]
2 changes: 1 addition & 1 deletion package/origlang-interop/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ impl OutputAccumulator for PseudoStdout {
TypeBox::Record(r) => r.to_string(),
};

echo(JsString::from(s));
echo(JsString::from(s.as_str()));
}

fn acc(&self) -> Option<Vec<TypeBox>> {
Expand Down
4 changes: 2 additions & 2 deletions package/origlang-parser/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ pub enum ParserErrorInner {
UnexpectedToken { pat: TokenKind, unmatch: Token },
#[error("Incomplete program snippet. Check hint for fix candidates. hint:{hint:?} state:{intermediate_state:?}")]
PartiallyParsed {
hint: Vec<PartiallyParseFixCandidate>,
intermediate_state: Vec<IntermediateStateCandidate>,
hint: Box<[PartiallyParseFixCandidate]>,
intermediate_state: Box<[IntermediateStateCandidate]>,
},
#[error("input sequence cannot be parsed as a int literal: {error}")]
UnParsableIntLiteral { error: ParseIntError },
Expand Down
6 changes: 3 additions & 3 deletions package/origlang-parser/src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -193,9 +193,9 @@ impl Parser {
Err(ParserError::new(
ParserErrorInner::PartiallyParsed {
hint: vec![PartiallyParseFixCandidate::InsertAfter {
tokens: vec![Token::NewLine],
}],
intermediate_state: vec![],
tokens: vec![Token::NewLine].into_boxed_slice(),
}].into_boxed_slice(),
intermediate_state: Box::new([]),
},
next.map_or(self.lexer.last_position, |x| x.position),
))
Expand Down
4 changes: 2 additions & 2 deletions package/origlang-parser/src/recover.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ pub enum PartiallyParseFixCandidate {
#[display(fmt = "No fixes available")]
None,
#[display(fmt = "Insert before")]
InsertBefore { tokens: Vec<Token> },
InsertBefore { tokens: Box<[Token]> },
#[display(fmt = "Insert after")]
InsertAfter { tokens: Vec<Token> },
InsertAfter { tokens: Box<[Token]> },
}
2 changes: 1 addition & 1 deletion package/origlang-runtime/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@ tap = "1.0.1"
origlang-typesystem-model = { path = "../origlang-typesystem-model" }
origlang-ast = { path = "../origlang-ast" }
origlang-ir = { path = "../origlang-ir" }
origlang-ir-optimizer = { path = "../origlang-ir-optimizer" }
origlang-type-stringify = { path = "../origlang-type-stringify" }
41 changes: 19 additions & 22 deletions package/origlang-runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@

mod invoke_once;

#[cfg(test)]
mod tests;

use derive_more::{Display, From};
use log::debug;
use origlang_ast::after_parse::BinaryOperatorKind;
Expand All @@ -13,7 +16,7 @@ use std::collections::{HashMap, VecDeque};
use std::fmt::{Debug, Display, Formatter};
use tap::Conv;
use thiserror::Error;

use origlang_type_stringify::write_comma_separated_items;
use crate::invoke_once::InvokeOnce;
use origlang_typesystem_model::{DisplayRecordType, Type, TypedFloatLiteral, TypedIntLiteral};

Expand All @@ -40,19 +43,16 @@ pub enum TypeBoxUnwrapError {}

#[derive(PartialEq, Clone, Debug)]
pub struct DisplayTupleValue {
pub boxes: Vec<TypeBox>,
pub boxes: Box<[TypeBox]>,
}

impl Display for DisplayTupleValue {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
let s = self
.boxes
.iter()
.map(ToString::to_string)
.collect::<Vec<_>>()
.join(", ");
let s = format!("({s})");
f.write_str(&s)
f.write_str("(")?;

write_comma_separated_items(f, &self.boxes)?;

f.write_str(")")
}
}

Expand All @@ -64,15 +64,12 @@ pub struct DisplayRecordValue {

impl Display for DisplayRecordValue {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
let s = self
.values
.iter()
.map(ToString::to_string)
.collect::<Vec<_>>()
.join(", ");
let name = &self.name;
let s = format!("{name} {{{s}}}");
f.write_str(&s)
f.write_str(self.name.as_name())?;
f.write_str(" {")?;

write_comma_separated_items(f, &self.values)?;

f.write_str("}")
}
}

Expand Down Expand Up @@ -128,12 +125,12 @@ impl TypeBox {
t.boxes
.iter()
.map(Self::get_type)
.collect::<Vec<_>>()
.collect::<Box<_>>()
.into(),
),
Self::Record(r) => Type::Record(DisplayRecordType::new(
r.name.clone(),
r.values.iter().map(Self::get_type).collect::<Vec<_>>(),
r.values.iter().map(Self::get_type).collect(),
)),
}
}
Expand Down Expand Up @@ -491,7 +488,7 @@ impl CanBeEvaluated for CompiledTypedExpression {
res.push(e.evaluate(runtime)?);
}

Ok(TypeBox::Tuple(DisplayTupleValue { boxes: res }))
Ok(TypeBox::Tuple(DisplayTupleValue { boxes: res.into_boxed_slice() }))
}
Self::ExtractTuple { expr, index } => {
let x = expr.evaluate(runtime)?;
Expand Down
80 changes: 80 additions & 0 deletions package/origlang-runtime/src/tests.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
mod display {
mod record {
use origlang_ast::Identifier;
use crate::{DisplayRecordValue, TypeBox};

#[test]
fn empty() {
let x = DisplayRecordValue {
name: Identifier::new("abcdef".to_string()),
values: vec![],
};

let x = format!("{x}");
assert_eq!(x, "abcdef {}");
}

#[test]
fn one() {
let x = DisplayRecordValue {
name: Identifier::new("abcdef".to_string()),
values: vec![
TypeBox::String("defg".to_string())
],
};

let x = format!("{x}");
assert_eq!(x, "abcdef {defg}");
}

#[test]
fn many() {
let x = DisplayRecordValue {
name: Identifier::new("abcdef".to_string()),
values: vec![
TypeBox::String("abcdef".to_string()),
TypeBox::String("ghijkl".to_string()),
TypeBox::String("alice".to_string())
],
};

let x = format!("{x}");
assert_eq!(x, "abcdef {abcdef, ghijkl, alice}");

}
}
mod tuple {
use crate::{DisplayTupleValue, TypeBox};

#[test]
fn empty() {
let x = DisplayTupleValue {
boxes: Box::new([]),
};

let x = format!("{x}");
assert_eq!(x, "()");
}

#[test]
fn one() {
let x = DisplayTupleValue {
boxes: Box::new([TypeBox::String("abcd".to_string())]),
};

let x = format!("{x}");
assert_eq!(x, "(abcd)");
}

#[test]
fn many() {
let x = DisplayTupleValue {
boxes: Box::new([TypeBox::String("abcd".to_string()), TypeBox::String("defg".to_string())]),
};

let x = format!("{x}");
assert_eq!(x, "(abcd, defg)");

}
}
}
7 changes: 7 additions & 0 deletions package/origlang-slice-in-box/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[package]
name = "origlang-slice-in-box"
version = "0.1.0"
edition = "2021"
license = "MIT"

[dependencies]
29 changes: 29 additions & 0 deletions package/origlang-slice-in-box/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
use std::mem::MaybeUninit;

pub type BoxedSlice<I> = Box<[I]>;

pub fn create_initialized_boxed_slice<I>(len: usize, mut create_element: impl FnMut(usize) -> I) -> BoxedSlice<I> {
let mut slice = Box::new_uninit_slice(len);
for (i, e) in slice.iter_mut().enumerate() {
e.write(create_element(i));
}

unsafe { assume_every_elements_are_initialized(slice) }
}

pub fn try_create_initialized_boxed_slice<I, E>(len: usize, mut try_create_element: impl FnMut(usize) -> Result<I, E>) -> Result<BoxedSlice<I>, E> {
let mut slice = Box::new_uninit_slice(len);
for (i, e) in slice.iter_mut().enumerate() {
e.write(try_create_element(i)?);
}

Ok(unsafe { assume_every_elements_are_initialized(slice) })
}

unsafe fn assume_every_elements_are_initialized<I>(half_baked_slice_in_box: BoxedSlice<MaybeUninit<I>>) -> BoxedSlice<I> {
let ptr = Box::into_raw(half_baked_slice_in_box);
// SAFETY: caller must initialize elements in the fed MaybeUninit-slice.
let slice = ptr as *mut [I];

unsafe { Box::from_raw(slice) }
}
2 changes: 1 addition & 1 deletion package/origlang-testsuite/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -621,7 +621,7 @@ print a
)
.expect("properly parsed and typed"),
&[TypeBox::Tuple(DisplayTupleValue {
boxes: vec![TypeBox::NonCoercedInteger(1), TypeBox::NonCoercedInteger(2)]
boxes: Box::new([TypeBox::NonCoercedInteger(1), TypeBox::NonCoercedInteger(2)])
})]
);

Expand Down
7 changes: 7 additions & 0 deletions package/origlang-type-stringify/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[package]
name = "origlang-type-stringify"
version = "0.1.0"
edition = "2021"
license = "MIT"

[dependencies]
20 changes: 20 additions & 0 deletions package/origlang-type-stringify/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#![no_std]

extern crate core as std;
extern crate alloc;

use alloc::string::ToString;
use std::fmt::Formatter;

pub fn write_comma_separated_items<
'formatter,
'values,
T: ToString + 'values
>(f: &mut Formatter<'formatter>, values: &'values [T]) -> std::fmt::Result {
for value in values.iter().take(values.len().max(1) - 1) {
f.write_str(&value.to_string())?;
f.write_str(", ")?;
}

values.last().map_or(Ok(()), |last| f.write_str(&last.to_string()))
}
1 change: 1 addition & 0 deletions package/origlang-typecheck/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@ license = "MIT"
[dependencies]
origlang-typesystem-model = { path = "../origlang-typesystem-model" }
origlang-ast = { path = "../origlang-ast" }
origlang-slice-in-box = { path = "../origlang-slice-in-box" }
log = "0.4.21"
thiserror = "2.0.0"
16 changes: 7 additions & 9 deletions package/origlang-typecheck/src/type_check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -336,19 +336,18 @@ fn desugar_recursive_pattern_match(
continue;
}
TypedExpression::Tuple { expressions } => {
let m = outer_destruction
let typed_statements_checked_result_collection = outer_destruction
.iter()
.zip(expressions)
.map(|(element_binding, expression)| {
handle_atomic_pattern(expression, element_binding, checker)
})
.collect::<Vec<_>>();
.collect::<Box<[_]>>();

let mut k = vec![];

for mx in m {
let Ok(y) = mx else { return mx };
k.extend(y);
for typed_statements_checked_result in typed_statements_checked_result_collection {
k.extend(typed_statements_checked_result?);
}

break Ok(k);
Expand Down Expand Up @@ -570,10 +569,9 @@ impl TypeChecker {
.ok_or(()),
},
TypeSignature::Tuple(x) => {
let mut types = Vec::with_capacity(x.capacity());
for ts in x {
types.push(self.lower_type_signature_into_type(ts)?);
}
let types = origlang_slice_in_box::try_create_initialized_boxed_slice(x.len(), |i| {
self.lower_type_signature_into_type(&x[i])
})?;

Ok(Type::tuple(types))
}
Expand Down
1 change: 1 addition & 0 deletions package/origlang-typesystem-model/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ license = "MPL-2.0"
derive_more = "0.99.17"
ordered-float = "4.5.0"
origlang-ast = { path = "../origlang-ast" }
origlang-type-stringify = { path = "../origlang-type-stringify"}
Loading