perf(library/type_context): add caching for type_context::infer

This commit is contained in:
Leonardo de Moura 2016-02-02 15:17:18 -08:00
parent bd52e58294
commit bc86e9f179
5 changed files with 41 additions and 13 deletions

View file

@ -264,11 +264,11 @@ class blastenv {
return m_benv.m_curr_state.mk_metavar(type);
}
virtual void push() override {
virtual void push_core() override {
m_stack.push_back(m_benv.m_curr_state.save_assignment());
}
virtual void pop() override {
virtual void pop_core() override {
m_benv.m_curr_state.restore_assignment(m_stack.back());
m_stack.pop_back();
}

View file

@ -35,6 +35,7 @@ void tmp_type_context::clear() {
m_eassignment.clear();
m_trail.clear();
m_scopes.clear();
clear_infer_cache();
}
void tmp_type_context::set_next_uvar_idx(unsigned next_idx) {
@ -111,7 +112,7 @@ expr tmp_type_context::mk_mvar(expr const & type) {
return mk_idx_metavar(idx, type);
}
void tmp_type_context::push() {
void tmp_type_context::push_core() {
m_scopes.push_back(scope());
scope & s = m_scopes.back();
s.m_uassignment_sz = m_uassignment.size();
@ -119,7 +120,7 @@ void tmp_type_context::push() {
s.m_trail_sz = m_trail.size();
}
void tmp_type_context::pop() {
void tmp_type_context::pop_core() {
lean_assert(!m_scopes.empty());
scope const & s = m_scopes.back();
unsigned old_sz = s.m_trail_sz;

View file

@ -77,8 +77,8 @@ public:
virtual level mk_uvar();
virtual expr mk_mvar(expr const &);
virtual void push();
virtual void pop();
virtual void push_core();
virtual void pop_core();
virtual unsigned get_num_check_points() const;
virtual void commit();

View file

@ -124,6 +124,16 @@ type_context::~type_context() {
delete m_local_gen;
}
void type_context::push() {
m_infer_cache.push();
push_core();
}
void type_context::pop() {
pop_core();
m_infer_cache.pop();
}
expr type_context::mk_internal_local(name const & n, expr const & type, binder_info const & bi) {
return mk_local(m_ngen.next(), n, type, bi);
}
@ -1187,7 +1197,9 @@ expr type_context::infer(expr const & e) {
lean_assert(!is_var(e));
lean_assert(closed(e));
check_system("infer_type");
auto it = m_infer_cache.find(e);
if (it != m_infer_cache.end())
return it->second;
expr r;
switch (e.kind()) {
case expr_kind::Local:
@ -1217,13 +1229,18 @@ expr type_context::infer(expr const & e) {
r = infer_app(e);
break;
}
// TODO(Leo): cache results if we have performance problems
m_infer_cache.insert(mk_pair(e, r));
return r;
}
void type_context::clear_cache() {
m_ci_cache.clear();
m_ss_cache.clear();
clear_infer_cache();
}
void type_context::clear_infer_cache() {
m_infer_cache.clear();
}
/** \brief If the constant \c e is a class, return its name */

View file

@ -5,8 +5,10 @@ Released under Apache 2.0 license as described in the file LICENSE.
Author: Leonardo de Moura
*/
#pragma once
#include <functional>
#include <memory>
#include <vector>
#include "util/scoped_map.h"
#include "kernel/environment.h"
#include "library/io_state.h"
#include "library/io_state_stream.h"
@ -184,6 +186,9 @@ class type_context {
We use it when inferring types and we want to be sure a type is Pi-type. */
bool m_relax_is_opaque;
typedef scoped_map<expr, expr, expr_hash, std::equal_to<expr>> infer_cache;
infer_cache m_infer_cache;
bool is_opaque(declaration const & d) const;
optional<expr> reduce_projection(expr const & e);
optional<expr> norm_ext(expr const & e);
@ -430,9 +435,9 @@ public:
virtual expr mk_mvar(expr const &) = 0;
/** \brief Save the current assignment and metavariable declarations */
virtual void push() = 0;
virtual void push_core() = 0;
/** \brief Retore assignment (inverse for push) */
virtual void pop() = 0;
virtual void pop_core() = 0;
/** \brief Return the number of checkpoints created using \c push and not popped yet. */
virtual unsigned get_num_check_points() const = 0;
/** \brief Keep the changes since last push */
@ -453,6 +458,9 @@ public:
bool has_assigned_uvar(levels const & ls) const;
bool has_assigned_uvar_mvar(expr const & e) const;
void push();
void pop();
/** \brief Expand macro using extension context */
optional<expr> expand_macro(expr const & m);
@ -524,8 +532,10 @@ public:
/** \brief Similar to \c force_assign but sets m_relax_is_opaque */
bool relaxed_force_assign(expr const & ma, expr const & v);
/** \brief Clear internal caches used to speedup computation */
/** \brief Clear all internal caches used to speedup computation */
void clear_cache();
/** \brief Clear internal type inference cache used to speedup computation */
void clear_infer_cache();
/** \brief Update configuration options.
Return true iff the new options do not change the behavior of the object.
@ -604,8 +614,8 @@ public:
virtual expr mk_mvar(expr const &);
virtual expr infer_local(expr const & e) const { return mlocal_type(e); }
virtual expr infer_metavar(expr const & e) const { return mlocal_type(e); }
virtual void push() { m_trail.push_back(m_assignment); }
virtual void pop() { lean_assert(!m_trail.empty()); m_assignment = m_trail.back(); m_trail.pop_back(); }
virtual void push_core() { m_trail.push_back(m_assignment); }
virtual void pop_core() { lean_assert(!m_trail.empty()); m_assignment = m_trail.back(); m_trail.pop_back(); }
virtual unsigned get_num_check_points() const { return m_trail.size(); }
virtual void commit() { lean_assert(!m_trail.empty()); m_trail.pop_back(); }
virtual optional<expr> mk_subsingleton_instance(expr const & type);