Skip to content

Commit

Permalink
Add monomorph cache prototype.
Browse files Browse the repository at this point in the history
  • Loading branch information
tritao committed Aug 28, 2022
1 parent 32376b4 commit c3aa5e7
Show file tree
Hide file tree
Showing 10 changed files with 202 additions and 76 deletions.
106 changes: 94 additions & 12 deletions de/src/declaration_engine/declaration_engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ use crate::{
TypedFunctionDeclaration, TypedStructDeclaration, TypedTraitDeclaration, TypedTraitFn,
TypedTraitImpl,
},
namespace::namespace::Namespace,
type_system::type_argument::TypeArgument,
types::pretty_print::PrettyPrint,
};

Expand Down Expand Up @@ -78,14 +80,54 @@ impl DeclarationEngine {
self.slab.get(index).expect_function()
}

// TODO(joao): consider only adding unique copies, if you get a non unique copy, throw it away
pub(crate) fn add_monomorphized_function_copy(
pub(crate) fn get_or_create_monomorphized_fn(
&mut self,
decl_id: DeclarationId,
type_arguments: &mut Vec<TypeArgument>,
namespace: &Namespace,
) -> Option<TypedFunctionDeclaration> {
// get the original function declaration
let mut typed_function_declaration = self.get_function(decl_id).unwrap();

let cached_fn_decl = self.get_monomorphized_function(decl_id, type_arguments);
if cached_fn_decl.is_some() {
return cached_fn_decl;
}

// monomorphize the function declaration into a new copy
crate::type_system::type_engine::monomorphize(
&mut typed_function_declaration,
type_arguments,
namespace,
self,
)
.unwrap();

// add the new copy to the declaration engine
let new_id = self.slab.insert(DeclarationWrapper::Function(
typed_function_declaration.clone(),
));
self.add_monomorphized_copy(decl_id, new_id);

Some(typed_function_declaration)
}

pub(crate) fn get_monomorphized_function(
&self,
original_id: DeclarationId,
new_copy: TypedFunctionDeclaration,
) {
let new_id = self.slab.insert(DeclarationWrapper::Function(new_copy));
self.add_monomorphized_copy(original_id, new_id)
type_arguments: &Vec<TypeArgument>,
) -> Option<TypedFunctionDeclaration> {
for copy in self.get_monomorphized_copies(original_id).iter() {
let monomorphized_fn_decl = match copy {
DeclarationWrapper::Function(fn_decl) => fn_decl,
_ => panic!(),
};

if &monomorphized_fn_decl.type_parameters == type_arguments {
return Some(monomorphized_fn_decl.clone());
}
}
None
}

pub(crate) fn get_monomorphized_function_copies(
Expand Down Expand Up @@ -133,14 +175,54 @@ impl DeclarationEngine {
self.slab.get(index).expect_struct()
}

// TODO(joao): consider only adding unique copies, if you get a non unique copy, throw it away
pub(crate) fn add_monomorphized_struct_copy(
pub(crate) fn get_or_create_monomorphized_struct(
&mut self,
decl_id: DeclarationId,
type_arguments: &mut Vec<TypeArgument>,
namespace: &Namespace,
) -> Option<TypedStructDeclaration> {
// get the original struct declaration
let mut typed_struct_declaration = self.get_struct(decl_id).unwrap();

let cached_struct_decl = self.get_monomorphized_struct(decl_id, type_arguments);
if cached_struct_decl.is_some() {
return cached_struct_decl;
}

// monomorphize the function declaration into a new copy
crate::type_system::type_engine::monomorphize(
&mut typed_struct_declaration,
type_arguments,
namespace,
self,
)
.unwrap();

// add the new copy to the declaration engine
let new_id = self
.slab
.insert(DeclarationWrapper::Struct(typed_struct_declaration.clone()));
self.add_monomorphized_copy(decl_id, new_id);

Some(typed_struct_declaration)
}

pub(crate) fn get_monomorphized_struct(
&self,
original_id: DeclarationId,
new_copy: TypedStructDeclaration,
) {
let new_id = self.slab.insert(DeclarationWrapper::Struct(new_copy));
self.add_monomorphized_copy(original_id, new_id)
type_arguments: &Vec<TypeArgument>,
) -> Option<TypedStructDeclaration> {
for copy in self.get_monomorphized_copies(original_id).iter() {
let monomorphized_struct_decl = match copy {
DeclarationWrapper::Struct(struct_decl) => struct_decl,
_ => panic!(),
};

if &monomorphized_struct_decl.type_parameters == type_arguments {
return Some(monomorphized_struct_decl.clone());
}
}
None
}

pub(crate) fn get_monomorphized_struct_copies(
Expand Down
6 changes: 3 additions & 3 deletions de/src/language/typed/typed_declaration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ impl PrettyPrint for TypedFunctionDeclaration {
}
}

#[derive(Clone, PartialEq, Debug)]
#[derive(Clone, Eq, PartialEq, PartialOrd, Ord, Debug)]
pub(crate) struct TypedFunctionParameter {
pub(crate) name: String,
pub(crate) type_id: TypeId,
Expand Down Expand Up @@ -280,7 +280,7 @@ impl PrettyPrint for TypedTraitImpl {
}
}

#[derive(Clone)]
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord)]
pub(crate) struct TypedStructDeclaration {
pub(crate) name: String,
pub(crate) type_parameters: Vec<TypeParameter>,
Expand Down Expand Up @@ -348,7 +348,7 @@ impl fmt::Display for TypedStructDeclaration {
}
}

#[derive(Clone, Hash, PartialEq, Eq)]
#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
pub struct TypedStructField {
pub(crate) name: String,
pub(crate) type_id: TypeId,
Expand Down
12 changes: 12 additions & 0 deletions de/src/namespace/function_signature.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use crate::{
type_system::{type_id::TypeId, type_parameter::TypeParameter},
};

#[derive(PartialEq, Eq, PartialOrd, Ord)]
pub(crate) struct TypedFunctionSignature {
#[allow(dead_code)]
pub(crate) name: String,
Expand All @@ -25,6 +26,17 @@ impl From<TypedFunctionDeclaration> for TypedFunctionSignature {
}
}

impl From<&TypedFunctionDeclaration> for TypedFunctionSignature {
fn from(decl: &TypedFunctionDeclaration) -> Self {
TypedFunctionSignature {
name: decl.name.clone(),
type_parameters: decl.type_parameters.clone(),
parameters: decl.parameters.clone(),
return_type: decl.return_type,
}
}
}

impl From<TypedTraitFn> for TypedFunctionSignature {
fn from(decl: TypedTraitFn) -> Self {
TypedFunctionSignature {
Expand Down
40 changes: 7 additions & 33 deletions de/src/semantic_analysis/inference/expression.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use crate::{
},
namespace::namespace::Namespace,
type_system::{
type_engine::{insert_type, monomorphize, unify_types},
type_engine::{insert_type, unify_types},
type_info::TypeInfo,
},
types::create_type_id::CreateTypeId,
Expand Down Expand Up @@ -53,28 +53,15 @@ pub(super) fn analyze_expression(
.expect_function()
.unwrap();

// get the original function declaration
let mut typed_function_declaration = declaration_engine.get_function(decl_id).unwrap();
let typed_function_declaration = declaration_engine
.get_or_create_monomorphized_fn(decl_id, &mut type_arguments, namespace)
.unwrap();

// make sure we have the correct number of arguments
if typed_function_declaration.parameters.len() != arguments.len() {
panic!();
}

// monomorphize the function declaration into a new copy
// TODO(joao): optimize this to cache repeated monomorphize copies
monomorphize(
&mut typed_function_declaration,
&mut type_arguments,
namespace,
declaration_engine,
)
.unwrap();

// add the new copy to the declaration engine
declaration_engine
.add_monomorphized_function_copy(decl_id, typed_function_declaration.clone());

// type check the arguments
let new_arguments = arguments
.into_iter()
Expand Down Expand Up @@ -113,22 +100,9 @@ pub(super) fn analyze_expression(
.expect_struct()
.unwrap();

// get the original struct declaration
let mut typed_struct_declaration = declaration_engine.get_struct(decl_id).unwrap();

// monomorphize the struct declaration into a new copy
// TODO(joao): optimize this to cache repeated monomorphize copies
monomorphize(
&mut typed_struct_declaration,
&mut type_arguments,
namespace,
declaration_engine,
)
.unwrap();

// add the new copy to the declaration engine
declaration_engine
.add_monomorphized_struct_copy(decl_id, typed_struct_declaration.clone());
let typed_struct_declaration = declaration_engine
.get_or_create_monomorphized_struct(decl_id, &mut type_arguments, namespace)
.unwrap();

// type check the fields
let given_fields_map: HashMap<_, _> = fields
Expand Down
2 changes: 1 addition & 1 deletion de/src/type_system/trait_constraint.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub(crate) struct TraitConstraint {
pub(crate) trait_name: String,
}
8 changes: 7 additions & 1 deletion de/src/type_system/type_argument.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::fmt;

use super::type_id::TypeId;
use super::{type_id::TypeId, type_parameter::TypeParameter};

#[derive(Debug, Clone)]
pub struct TypeArgument {
Expand All @@ -12,3 +12,9 @@ impl fmt::Display for TypeArgument {
write!(f, "{}", self.type_id)
}
}

impl PartialEq<TypeParameter> for TypeArgument {
fn eq(&self, other: &TypeParameter) -> bool {
self.type_id == other.type_id
}
}
39 changes: 15 additions & 24 deletions de/src/type_system/type_engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -185,32 +185,23 @@ impl TypeEngine {
_ => Err("could not find generic declaration".to_string()),
},
TypeInfo::Ref(id) => Ok(id),
TypeInfo::Custom { name } => {
match namespace.get_symbol(&name)? {
TypedDeclaration::Struct(decl_id) => {
// get the original struct declaration
let mut struct_decl = declaration_engine.get_struct(decl_id).unwrap();
TypeInfo::Custom { name } => match namespace.get_symbol(&name)? {
TypedDeclaration::Struct(decl_id) => {
let mut type_arguments = vec![];
let struct_decl = declaration_engine
.get_or_create_monomorphized_struct(decl_id, &mut type_arguments, namespace)
.unwrap();

// monomorphize the struct declaration into a new copy
// TODO(joao): optimize this to cache repeated monomorphize copies
monomorphize(&mut struct_decl, &mut [], namespace, declaration_engine)
.unwrap();

// add the new copy to the declaration engine
declaration_engine
.add_monomorphized_struct_copy(decl_id, struct_decl.clone());

Ok(struct_decl.create_type_id())
}
TypedDeclaration::GenericTypeForFunctionScope { type_id, .. } => {
Ok(insert_type(TypeInfo::Ref(type_id)))
}
got => Err(format!(
"err, found: {}",
got.pretty_print(declaration_engine)
)),
Ok(struct_decl.create_type_id())
}
}
TypedDeclaration::GenericTypeForFunctionScope { type_id, .. } => {
Ok(insert_type(TypeInfo::Ref(type_id)))
}
got => Err(format!(
"err, found: {}",
got.pretty_print(declaration_engine)
)),
},
o => Ok(insert_type(o)),
}
}
Expand Down
2 changes: 1 addition & 1 deletion de/src/type_system/type_id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use super::type_engine::{insert_type, look_up_type_id, look_up_type_id_raw};
use super::type_info::TypeInfo;
use super::type_mapping::TypeMapping;

#[derive(Eq, Clone, Copy, Debug)]
#[derive(Eq, Clone, Copy, PartialOrd, Ord, Debug)]
pub struct TypeId(usize);

impl std::ops::Deref for TypeId {
Expand Down
9 changes: 8 additions & 1 deletion de/src/type_system/type_parameter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@ use std::hash::Hash;
use crate::types::copy_types::CopyTypes;

use super::trait_constraint::TraitConstraint;
use super::type_argument::TypeArgument;
use super::type_id::TypeId;
use super::type_mapping::TypeMapping;

#[derive(Debug, Clone, PartialEq, Eq, Hash)]
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct TypeParameter {
pub(crate) name: String,
pub(crate) type_id: TypeId,
Expand All @@ -25,3 +26,9 @@ impl fmt::Display for TypeParameter {
write!(f, "{}", self.type_id)
}
}

impl PartialEq<TypeArgument> for TypeParameter {
fn eq(&self, other: &TypeArgument) -> bool {
self.type_id == other.type_id
}
}
Loading

0 comments on commit c3aa5e7

Please sign in to comment.