This PR makes Lean code generation respect the module name provided through `lean --setup`. This is accomplished by porting to Lean the portion of `shell.cpp` that spans running the frontend to exiting the process. This makes it easier to load the module setup and control how its name is passed to the code generation functions. This port attempts to minimize the changes made to Lean. It marks the new Lean functions `private` and tries to preserve as faithfully as possible the behavior of the original C++ code. Exposing the new Lean interface publicly and/or further improving the code now that is written in Lean is left for the future.
91 lines
2.9 KiB
C++
91 lines
2.9 KiB
C++
/*
|
||
Copyright (c) 2018 Microsoft Corporation. All rights reserved.
|
||
Released under Apache 2.0 license as described in the file LICENSE.
|
||
|
||
Author: Sebastian Ullrich
|
||
*/
|
||
#include <string>
|
||
#include <map>
|
||
#include "library/time_task.h"
|
||
#include "kernel/trace.h"
|
||
|
||
namespace lean {
|
||
|
||
static std::map<std::string, second_duration> * g_cum_times;
|
||
static mutex * g_cum_times_mutex;
|
||
LEAN_THREAD_PTR(time_task, g_current_time_task);
|
||
|
||
bool has_no_block_profiling_task() {
|
||
return g_current_time_task != nullptr && g_current_time_task->category() != "blocked";
|
||
}
|
||
void report_profiling_time(std::string const & category, second_duration time) {
|
||
lock_guard<mutex> _(*g_cum_times_mutex);
|
||
(*g_cum_times)[category] += time;
|
||
}
|
||
void exclude_profiling_time_from_current_task(second_duration time) {
|
||
if (g_current_time_task)
|
||
g_current_time_task->exclude_duration(time);
|
||
}
|
||
|
||
void display_cumulative_profiling_times(std::ostream & out) {
|
||
if (g_cum_times->empty())
|
||
return;
|
||
sstream ss;
|
||
ss << "cumulative profiling times:\n";
|
||
for (auto const & p : *g_cum_times)
|
||
ss << "\t" << p.first << " " << display_profiling_time{p.second} << "\n";
|
||
// output atomically, like IO.print
|
||
out << ss.str();
|
||
}
|
||
|
||
/* displayCumulativeProfilingTimes : BaseIO Unit */
|
||
extern "C" LEAN_EXPORT obj_res lean_display_cumulative_profiling_times(obj_arg) {
|
||
display_cumulative_profiling_times(std::cerr);
|
||
return lean_io_result_mk_ok(box(0));
|
||
}
|
||
|
||
void initialize_time_task() {
|
||
g_cum_times_mutex = new mutex;
|
||
g_cum_times = new std::map<std::string, second_duration>;
|
||
}
|
||
|
||
void finalize_time_task() {
|
||
delete g_cum_times;
|
||
delete g_cum_times_mutex;
|
||
}
|
||
|
||
time_task::time_task(std::string const & category, options const & opts, name decl) :
|
||
m_category(category) {
|
||
if (get_profiler(opts)) {
|
||
m_timeit = optional<xtimeit>(get_profiling_threshold(opts), [=](second_duration duration) mutable {
|
||
sstream ss;
|
||
ss << m_category;
|
||
if (decl)
|
||
ss << " of " << decl;
|
||
ss << " took " << display_profiling_time{duration} << "\n";
|
||
// output atomically, like IO.print
|
||
tout() << ss.str();
|
||
});
|
||
m_parent_task = g_current_time_task;
|
||
g_current_time_task = this;
|
||
}
|
||
}
|
||
|
||
time_task::~time_task() {
|
||
if (m_timeit) {
|
||
g_current_time_task = m_parent_task;
|
||
report_profiling_time(m_category, m_timeit->get_elapsed());
|
||
if (m_parent_task && m_parent_task->m_timeit)
|
||
// report exclusive times
|
||
m_parent_task->m_timeit->exclude_duration(m_timeit->get_elapsed_inclusive());
|
||
}
|
||
}
|
||
|
||
/* profileit {α : Type} (category : String) (opts : Options) (fn : Unit → α) (decl : Name) : α */
|
||
extern "C" LEAN_EXPORT obj_res lean_profileit(b_obj_arg category, b_obj_arg opts, obj_arg fn, obj_arg decl) {
|
||
time_task t(string_to_std(category),
|
||
TO_REF(options, opts),
|
||
name(decl));
|
||
return apply_1(fn, box(0));
|
||
}
|
||
}
|