added proper template function instantiation caching

This commit is contained in:
Nathan Braswell
2016-02-03 21:57:06 -05:00
parent 1ea07d4f92
commit de3ead0573
5 changed files with 49 additions and 22 deletions

View File

@@ -321,6 +321,7 @@ obj function_template (Object) {
var instantiated: vector<*ast_node> var instantiated: vector<*ast_node>
var template_types: vector<string> var template_types: vector<string>
var template_type_replacements: map<string, *type> var template_type_replacements: map<string, *type>
var instantiated_map: map<vector<type>, *ast_node>
var scope: map<string, vector<*ast_node>> var scope: map<string, vector<*ast_node>>
fun construct(name_in: string, syntax_node_in: *tree<symbol>, template_types_in: vector<string>, template_type_replacements_in: map<string, *type>): *function_template { fun construct(name_in: string, syntax_node_in: *tree<symbol>, template_types_in: vector<string>, template_type_replacements_in: map<string, *type>): *function_template {
name.copy_construct(&name_in) name.copy_construct(&name_in)
@@ -328,6 +329,7 @@ obj function_template (Object) {
instantiated.construct() instantiated.construct()
template_types.copy_construct(&template_types_in) template_types.copy_construct(&template_types_in)
template_type_replacements.copy_construct(&template_type_replacements_in) template_type_replacements.copy_construct(&template_type_replacements_in)
instantiated_map.construct()
scope.construct() scope.construct()
return this return this
} }
@@ -337,6 +339,7 @@ obj function_template (Object) {
instantiated.copy_construct(&old->instantiated) instantiated.copy_construct(&old->instantiated)
template_types.copy_construct(&old->template_types) template_types.copy_construct(&old->template_types)
template_type_replacements.copy_construct(&old->template_type_replacements) template_type_replacements.copy_construct(&old->template_type_replacements)
instantiated_map.copy_construct(&old->instantiated_map)
scope.copy_construct(&old->scope) scope.copy_construct(&old->scope)
} }
fun destruct() { fun destruct() {
@@ -344,6 +347,7 @@ obj function_template (Object) {
instantiated.destruct() instantiated.destruct()
template_types.destruct() template_types.destruct()
template_type_replacements.destruct() template_type_replacements.destruct()
instantiated_map.destruct()
scope.destruct() scope.destruct()
} }
fun operator=(other: ref function_template) { fun operator=(other: ref function_template) {
@@ -352,7 +356,8 @@ obj function_template (Object) {
} }
fun operator==(other: ref function_template): bool { fun operator==(other: ref function_template): bool {
return name == name && syntax_node == other.syntax_node && instantiated == other.instantiated && return name == name && syntax_node == other.syntax_node && instantiated == other.instantiated &&
scope == other.scope && template_types == other.template_types && template_type_replacements == other.template_type_replacements scope == other.scope && template_types == other.template_types && template_type_replacements == other.template_type_replacements &&
instantiated_map == other.instantiated_map
} }
} }
fun ast_code_block_ptr(): *ast_node { fun ast_code_block_ptr(): *ast_node {

View File

@@ -495,32 +495,43 @@ fun find_or_instantiate_function_template(identifier: *tree<symbol>, template_in
var name = concat_symbol_tree(identifier) var name = concat_symbol_tree(identifier)
var results = scope_lookup(name, scope) var results = scope_lookup(name, scope)
var real_types = get_nodes("type", template_inst).map(fun(t: *tree<symbol>): *type return transform_type(t, scope, map<string, *type>());) var real_types = get_nodes("type", template_inst).map(fun(t: *tree<symbol>): *type return transform_type(t, scope, map<string, *type>());)
var real_types_deref = real_types.map(fun(t:*type):type return *t;)
for (var i = 0; i < results.size; i++;) { for (var i = 0; i < results.size; i++;) {
if (is_function_template(results[i])) { if (is_function_template(results[i])) {
var template_types = results[i]->function_template.template_types var template_types = results[i]->function_template.template_types
var template_type_replacements = results[i]->function_template.template_type_replacements var template_type_replacements = results[i]->function_template.template_type_replacements
if (template_types.size != real_types.size) if (template_types.size != real_types.size)
continue continue
println("FOR FIND OR INSTATINTATE PREEEE") // check if already instantiated
template_type_replacements.for_each(fun(key: string, value: *type) println(string("MAP: ") + key + " : " + value->to_string());) var inst_func = null<ast_node>()
println("MAP DONE") if (results[i]->function_template.instantiated_map.contains_key(real_types_deref)) {
for (var j = 0; j < template_types.size; j++;) { println("USING CACHED TEMPLATE FUNCITON")
template_type_replacements[template_types[j]] = real_types[j] inst_func = results[i]->function_template.instantiated_map[real_types_deref]
println("Just made") } else {
println(template_types[j]) println("FOR FIND OR INSTATINTATE PREEEE")
println("equal to") template_type_replacements.for_each(fun(key: string, value: *type) println(string("MAP: ") + key + " : " + value->to_string());)
println(real_types[j]->to_string()) println("MAP DONE")
for (var j = 0; j < template_types.size; j++;) {
template_type_replacements[template_types[j]] = real_types[j]
println("Just made")
println(template_types[j])
println("equal to")
println(real_types[j]->to_string())
}
println("FOR FIND OR INSTATINTATE")
template_type_replacements.for_each(fun(key: string, value: *type) println(string("MAP: ") + key + " : " + value->to_string());)
println("MAP DONE")
inst_func = second_pass_function(results[i]->function_template.syntax_node, results[i], template_type_replacements, false)
// and fully instantiate it
inst_func->function.body_statement = transform_statement(get_node("statement", results[i]->function_template.syntax_node), inst_func)
// add to instantiated_map so we only instantiate with a paticular set of types once
results[i]->function_template.instantiated_map.set(real_types_deref, inst_func)
} }
println("FOR FIND OR INSTATINTATE") if (function_satisfies_params(inst_func, param_types))
template_type_replacements.for_each(fun(key: string, value: *type) println(string("MAP: ") + key + " : " + value->to_string());) return inst_func
println("MAP DONE")
var part_instantiated = second_pass_function(results[i]->function_template.syntax_node, results[i], template_type_replacements, false)
// and fully instantiate it
part_instantiated->function.body_statement = transform_statement(get_node("statement", results[i]->function_template.syntax_node), part_instantiated)
if (function_satisfies_params(part_instantiated, param_types))
return part_instantiated
} }
} }
println("FREAK OUT MACHINE") println("FREAK OUT MACHINE")

View File

@@ -109,9 +109,13 @@ obj type (Object) {
} }
fun operator!=(other: ref type):bool return !(*this == other); fun operator!=(other: ref type):bool return !(*this == other);
fun operator==(other: ref type):bool { fun operator==(other: ref type):bool {
if ( (return_type && other.return_type && *return_type != *other.return_type) || (return_type && !other.return_type) || (!return_type && other.return_type) ) if (parameter_types.size != other.parameter_types.size)
return false return false
return base == other.base && parameter_types == other.parameter_types && indirection == other.indirection && type_def == other.type_def && traits == other.traits for (var i = 0; i < parameter_types.size; i++;)
if (!deref_equality(parameter_types[i], other.parameter_types[i]))
return false
return base == other.base && deref_equality(return_type, other.return_type) &&
indirection == other.indirection && deref_equality(type_def, other.type_def) && traits == other.traits
} }
fun to_string(): string { fun to_string(): string {
var all_string = string("traits:[") var all_string = string("traits:[")

View File

@@ -5,6 +5,12 @@ import serialize
// maybe my favorite function // maybe my favorite function
fun do_nothing() {} fun do_nothing() {}
fun deref_equality<T>(a: *T, b: *T): bool {
if ( (a && b && !(*a == *b)) || (a && !b) || (!a && b) )
return false
return true
}
fun max<T>(a: T, b: T): T { fun max<T>(a: T, b: T): T {
if (a > b) if (a > b)
return a; return a;

View File

@@ -48,6 +48,7 @@ fun some_other_function(in: bool): float {
fun main(): int { fun main(): int {
var a = id<int>(7) var a = id<int>(7)
simple_println(a) simple_println(a)
var b = id<int>(8)
/*var b = id<*char>("Double down time")*/ /*var b = id<*char>("Double down time")*/
/*simple_println(b)*/ /*simple_println(b)*/
simple_println(id<char>("Double down time")) simple_println(id<char>("Double down time"))