mirror of
https://github.com/Z3Prover/z3
synced 2025-04-09 19:01:50 +00:00
161 lines
3.8 KiB
C++
161 lines
3.8 KiB
C++
/*++
|
|
Copyright (c) 2006 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
dl_costs.cpp
|
|
|
|
Abstract:
|
|
|
|
<abstract>
|
|
|
|
Author:
|
|
|
|
Krystof Hoder (t-khoder) 2010-09-20.
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include "debug.h"
|
|
#include "stopwatch.h"
|
|
#include "dl_context.h"
|
|
#include "dl_rule.h"
|
|
#include "dl_costs.h"
|
|
|
|
namespace datalog {
|
|
|
|
// -----------------------------------
|
|
//
|
|
// costs
|
|
//
|
|
// -----------------------------------
|
|
|
|
costs::costs() : milliseconds(0), instructions(0) {}
|
|
|
|
bool costs::empty() const {
|
|
return !milliseconds && !instructions;
|
|
}
|
|
|
|
void costs::reset() {
|
|
milliseconds = 0;
|
|
instructions = 0;
|
|
}
|
|
|
|
costs costs::operator-(const costs & o) const {
|
|
costs res(*this);
|
|
SASSERT(milliseconds>o.milliseconds);
|
|
res.milliseconds-=o.milliseconds;
|
|
SASSERT(instructions>o.instructions);
|
|
res.instructions-=o.instructions;
|
|
return res;
|
|
}
|
|
|
|
void costs::operator+=(const costs & o) {
|
|
milliseconds+=o.milliseconds;
|
|
instructions+=o.instructions;
|
|
}
|
|
|
|
bool costs::passes_thresholds(context & ctx) const {
|
|
return milliseconds >= ctx.dl_profile_milliseconds_threshold();
|
|
}
|
|
|
|
void costs::output(std::ostream & out) const {
|
|
out << "instr: " << instructions << " time: " << milliseconds << "ms";
|
|
}
|
|
|
|
|
|
// -----------------------------------
|
|
//
|
|
// accounted_object
|
|
//
|
|
// -----------------------------------
|
|
|
|
accounted_object::~accounted_object() {
|
|
if(m_parent_object) {
|
|
SASSERT(m_context);
|
|
m_context->get_rule_manager().dec_ref(m_parent_object);
|
|
}
|
|
}
|
|
|
|
void accounted_object::set_accounting_parent_object(context & ctx, rule * parent) {
|
|
if(m_parent_object) {
|
|
SASSERT(m_context);
|
|
SASSERT(m_context==&ctx);
|
|
m_context->get_rule_manager().dec_ref(m_parent_object);
|
|
}
|
|
m_context = &ctx;
|
|
m_parent_object = parent;
|
|
m_context->get_rule_manager().inc_ref(m_parent_object);
|
|
}
|
|
|
|
void accounted_object::process_costs() {
|
|
costs delta = get_current_costs();
|
|
if(delta.empty()) {
|
|
return;
|
|
}
|
|
get_current_costs().reset();
|
|
accounted_object * obj = this;
|
|
do {
|
|
obj->m_processed_cost+=delta;
|
|
obj=obj->m_parent_object;
|
|
} while(obj);
|
|
}
|
|
|
|
void accounted_object::get_total_cost(costs & result) const {
|
|
result.reset();
|
|
result+=m_current_cost;
|
|
result+=m_processed_cost;
|
|
}
|
|
|
|
bool accounted_object::passes_output_thresholds(context & ctx) const {
|
|
costs c;
|
|
get_total_cost(c);
|
|
return c.passes_thresholds(ctx);
|
|
}
|
|
|
|
|
|
void accounted_object::output_profile(context & ctx, std::ostream & out) const {
|
|
costs c;
|
|
get_total_cost(c);
|
|
c.output(out);
|
|
}
|
|
|
|
|
|
// -----------------------------------
|
|
//
|
|
// cost_recorder
|
|
//
|
|
// -----------------------------------
|
|
|
|
cost_recorder::cost_recorder() : m_obj(0) {
|
|
m_stopwatch = alloc(stopwatch);
|
|
m_stopwatch->start();
|
|
}
|
|
|
|
cost_recorder::~cost_recorder() {
|
|
if(m_obj) {
|
|
finish();
|
|
}
|
|
dealloc(m_stopwatch);
|
|
}
|
|
|
|
void cost_recorder::start(accounted_object * obj) {
|
|
uint64 curr_time = static_cast<uint64>(m_stopwatch->get_current_seconds()*1000);
|
|
if(m_obj) {
|
|
costs::time_type time_delta = static_cast<costs::time_type>(curr_time-m_last_time);
|
|
costs & c = m_obj->get_current_costs();
|
|
c.instructions++;
|
|
c.milliseconds+=time_delta;
|
|
m_obj->m_being_recorded = false;
|
|
}
|
|
m_running = obj!=0;
|
|
m_obj = obj;
|
|
m_last_time = curr_time;
|
|
if(obj) {
|
|
m_obj->m_being_recorded = true;
|
|
}
|
|
}
|
|
|
|
};
|