From f12fbce0f51d58b429afd8a359aeb8a3b27a4eb0 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sun, 18 Dec 2016 18:23:46 -0500 Subject: IR: memoize compile-time evaluated fn invocations --- src/analyze.cpp | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) (limited to 'src/analyze.cpp') diff --git a/src/analyze.cpp b/src/analyze.cpp index 7651742986..950254b7e9 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -2693,6 +2693,54 @@ bool generic_fn_type_id_eql(GenericFnTypeId *a, GenericFnTypeId *b) { return true; } +uint32_t fn_eval_hash(Scope* scope) { + uint32_t result = 0; + while (scope) { + if (scope->id == ScopeIdVarDecl) { + ScopeVarDecl *var_scope = (ScopeVarDecl *)scope; + result += hash_const_val(var_scope->var->type, var_scope->var->value); + } else if (scope->id == ScopeIdFnDef) { + ScopeFnDef *fn_scope = (ScopeFnDef *)scope; + result += hash_ptr(fn_scope->fn_entry); + return result; + } else { + zig_unreachable(); + } + + scope = scope->parent; + } + zig_unreachable(); +} + +bool fn_eval_eql(Scope *a, Scope *b) { + while (a && b) { + if (a->id != b->id) + return false; + + if (a->id == ScopeIdVarDecl) { + ScopeVarDecl *a_var_scope = (ScopeVarDecl *)a; + ScopeVarDecl *b_var_scope = (ScopeVarDecl *)b; + if (a_var_scope->var->type != b_var_scope->var->type) + return false; + if (!const_values_equal(a_var_scope->var->value, b_var_scope->var->value, a_var_scope->var->type)) + return false; + } else if (a->id == ScopeIdFnDef) { + ScopeFnDef *a_fn_scope = (ScopeFnDef *)a; + ScopeFnDef *b_fn_scope = (ScopeFnDef *)b; + if (a_fn_scope->fn_entry != b_fn_scope->fn_entry) + return false; + + return true; + } else { + zig_unreachable(); + } + + a = a->parent; + b = b->parent; + } + return false; +} + bool type_has_bits(TypeTableEntry *type_entry) { assert(type_entry); assert(type_entry->id != TypeTableEntryIdInvalid); -- cgit v1.2.3