Skip to content

Commit 9b63c84

Browse files
authored
Merge pull request diffblue#363 from diffblue/micro_time_profiler
Added micro time profiler
2 parents a7f834a + c9f4837 commit 9b63c84

File tree

5 files changed

+300
-0
lines changed

5 files changed

+300
-0
lines changed

src/pointer-analysis/local_value_set.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <util/infix.h>
1111
#include <util/suffix.h>
1212
#include <util/c_types.h>
13+
#include <util/tmprof.h>
1314

1415
#include <pointer-analysis/dynamic_object_name.h>
1516

@@ -87,6 +88,8 @@ void local_value_sett::get_may_alias_set(
8788
value_setst::valuest &dest,
8889
const namespacet &ns) const
8990
{
91+
TMPROF_BLOCK();
92+
9093
object_mapt pointed_objects;
9194
get_value_set(expr, pointed_objects, ns, false);
9295
std::vector<exprt> uniform_pointed_objects;

src/taint-analysis/taint_security_scanner.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include <util/config.h>
1818
#include <util/msgstream.h>
1919
#include <util/json_map_serializer.h>
20+
#include <util/tmprof.h>
2021
#include "taint_serializer_traits.h"
2122
#include <iomanip>
2223
#include <memory>
@@ -336,6 +337,9 @@ bool taint_do_security_scan(
336337

337338
logger.status() << "The security scanner has finished successfully."
338339
<< messaget::eom;
340+
tmprof_dump_as_json(
341+
boost::filesystem::path(config.get_output_root_directory()) /
342+
"TMPROF.json");
339343
return true;
340344
}
341345
catch(const std::exception &e)

src/taint-analysis/taint_summary.cpp

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ This module defines interfaces and functionality for taint summaries.
2121
#include <summaries/summary_dump.h>
2222
#include <pointer-analysis/local_value_set_analysis.h>
2323
#include <goto-programs/remove_returns.h>
24+
#include <util/tmprof.h>
2425
#include <util/std_types.h>
2526
#include <util/file_util.h>
2627
#include <util/msgstream.h>
@@ -71,6 +72,8 @@ void expand_external_objects(
7172
const object_numbers_by_fieldnamet& by_fieldname,
7273
const object_numberingt& taint_object_numbering)
7374
{
75+
TMPROF_BLOCK();
76+
7477
// Whenever a value like external_value_set("external_objects.x") occurs,
7578
// expand that to include the 'x' fields of all objects we know about,
7679
// as what is external to the callee might be local to us.
@@ -112,6 +115,8 @@ void expand_external_objects(
112115

113116
static exprt transform_external_objects(const exprt& e)
114117
{
118+
TMPROF_BLOCK();
119+
115120
if(e.id()==ID_member && get_underlying_object(e).id()==ID_external_value_set)
116121
{
117122
// Rewrite member(externals, "x") as externals("x"), to make subsequent
@@ -167,6 +172,8 @@ static void collect_lvsa_access_paths(
167172
instruction_iteratort const& instit,
168173
std::set<exprt> &result)
169174
{
175+
TMPROF_BLOCK();
176+
170177
if(query_in.id()==ID_side_effect)
171178
{
172179
side_effect_exprt const see=to_side_effect_expr(query_in);
@@ -245,6 +252,8 @@ static void collect_lvsa_access_paths(
245252
lvalue_numbers_sett& result,
246253
bool &singular)
247254
{
255+
TMPROF_BLOCK();
256+
248257
std::set<exprt> referees;
249258
collect_lvsa_access_paths(
250259
query_in,
@@ -274,6 +283,8 @@ static void collect_lvsa_alias_access_paths(
274283
object_numberingt& taint_object_numbering,
275284
lvalue_numbers_sett& result)
276285
{
286+
TMPROF_BLOCK();
287+
277288
value_setst::valuest dest;
278289
lvsa.get_may_alias_values(inst_it, query_in, dest);
279290
for(const exprt &object : dest)
@@ -288,6 +299,8 @@ static void collect_lvsa_access_paths(
288299
instruction_iteratort const& instit,
289300
object_numberingt& taint_object_numbering)
290301
{
302+
TMPROF_BLOCK();
303+
291304
bool singular=false;
292305

293306
collect_lvsa_access_paths(
@@ -308,6 +321,8 @@ static void populate_formals_to_actuals(
308321
object_numberingt& taint_object_numbering,
309322
formals_to_actuals_mapt& formals_to_actuals)
310323
{
324+
TMPROF_BLOCK();
325+
311326
for(auto instit=prog.instructions.begin(),instend=prog.instructions.end();
312327
instit!=instend; ++instit)
313328
{
@@ -382,6 +397,8 @@ numbered_lvalue_to_taint_mapt taint_algorithm_computing_summary_of_functiont::
382397
const numbered_lvalue_to_taint_mapt &a,
383398
const numbered_lvalue_to_taint_mapt &b)
384399
{
400+
TMPROF_BLOCK();
401+
385402
numbered_lvalue_to_taint_mapt result_dict;
386403
if(a.get_base()==b.get_base())
387404
{
@@ -428,6 +445,8 @@ numbered_lvalue_to_taint_mapt taint_algorithm_computing_summary_of_functiont::
428445
const numbered_lvalue_to_taint_mapt &a,
429446
const numbered_lvalue_to_taint_mapt &b)
430447
{
448+
TMPROF_BLOCK();
449+
431450
numbered_lvalue_to_taint_mapt result = a;
432451
for(auto b_it=b.cbegin(); b_it!=b.cend(); ++b_it)
433452
assign(result, b_it->first, b_it->second);
@@ -439,6 +458,8 @@ void taint_algorithm_computing_summary_of_functiont::assign(
439458
taint_lvalue_numbert const lvalue,
440459
const taint_sett &taint)
441460
{
461+
TMPROF_BLOCK();
462+
442463
auto const it = map.find(lvalue);
443464
if (it == map.end())
444465
{
@@ -454,6 +475,8 @@ void taint_algorithm_computing_summary_of_functiont::maybe_assign(
454475
taint_lvalue_numbert const lvalue,
455476
const taint_sett &taint)
456477
{
478+
TMPROF_BLOCK();
479+
457480
auto const it = map.find(lvalue);
458481
if (it == map.end())
459482
{
@@ -471,6 +494,8 @@ bool taint_algorithm_computing_summary_of_functiont::proper_subset(
471494
const numbered_lvalue_to_taint_mapt &a,
472495
const numbered_lvalue_to_taint_mapt &b)
473496
{
497+
TMPROF_BLOCK();
498+
474499
if(b.empty())
475500
return false;
476501
bool common_base=a.get_base()==b.get_base();
@@ -492,6 +517,8 @@ bool taint_algorithm_computing_summary_of_functiont::subset(
492517
const numbered_lvalue_to_taint_mapt &a,
493518
const numbered_lvalue_to_taint_mapt &b)
494519
{
520+
TMPROF_BLOCK();
521+
495522
return a==b || proper_subset(a,b);
496523
}
497524

@@ -506,6 +533,8 @@ void taint_algorithm_computing_summary_of_functiont::
506533
const instruction_iteratort &Iit,
507534
const irep_idt &caller_ident)
508535
{
536+
TMPROF_BLOCK();
537+
509538
auto parameter_indices=fn_type.parameter_indices();
510539

511540
for (const std::pair<taint_lvalue_numbert, taint_variablet>& input
@@ -568,6 +597,8 @@ void taint_algorithm_computing_summary_of_functiont::
568597
const instruction_iteratort &Iit,
569598
local_value_set_analysist &lvsa)
570599
{
600+
TMPROF_BLOCK();
601+
571602
auto parameter_indices=fn_type.parameter_indices();
572603

573604
for(const std::pair<taint_lvalue_numbert, taint_sett>& lvalue_taint :
@@ -650,6 +681,8 @@ void taint_algorithm_computing_summary_of_functiont::initialise_domain(
650681
const std::map<goto_programt::const_targett, goto_programt::const_targetst>
651682
&inst_predecessors)
652683
{
684+
TMPROF_BLOCK();
685+
653686
// TODO: Improve this to only count as inputs those values which might be read
654687
// without a preceding write within the same function.
655688
lvalue_numbers_sett environment;
@@ -880,6 +913,8 @@ void taint_algorithm_computing_summary_of_functiont::handle_assignment(
880913
instruction_iteratort const& Iit,
881914
local_value_set_analysist &lvsa)
882915
{
916+
TMPROF_BLOCK();
917+
883918
const auto& lhs_type=program->get_namespace().follow(asgn.lhs().type());
884919
if(lhs_type.id()==ID_struct)
885920
{
@@ -950,6 +985,8 @@ taint_sett taint_algorithm_computing_summary_of_functiont::
950985
local_value_set_analysist &lvsa,
951986
const numbered_lvalue_to_taint_mapt &a)
952987
{
988+
TMPROF_BLOCK();
989+
953990
lvalue_numbers_sett numbers_of_aliases;
954991
collect_lvsa_access_paths(
955992
lvalue,
@@ -977,6 +1014,8 @@ void taint_algorithm_computing_summary_of_functiont::
9771014
local_value_set_analysist &lvsa,
9781015
numbered_lvalue_to_taint_mapt &result)
9791016
{
1017+
TMPROF_BLOCK();
1018+
9801019
lvalue_numbers_sett numbers_of_aliases;
9811020
bool singular=false;
9821021
collect_lvsa_access_paths(
@@ -1020,6 +1059,8 @@ numbered_lvalue_to_taint_mapt taint_algorithm_computing_summary_of_functiont::
10201059
local_value_set_analysist &lvsa,
10211060
taint_transition_propertiest &transition_properties)
10221061
{
1062+
TMPROF_BLOCK();
1063+
10231064
goto_programt::instructiont const& I=*Iit;
10241065
numbered_lvalue_to_taint_mapt result;
10251066
// Take a cheap read-only view of the incoming domain:
@@ -1028,6 +1069,8 @@ numbered_lvalue_to_taint_mapt taint_algorithm_computing_summary_of_functiont::
10281069
{
10291070
case ASSIGN:
10301071
{
1072+
TMPROF_BLOCK();
1073+
10311074
transition_properties[Iit].push_back(
10321075
{taint_transition_property_typet::ASSIGNMENT, taint_rule_idt{}, ""});
10331076
const code_assignt &asgn=to_code_assign(I.code);
@@ -1089,6 +1132,8 @@ numbered_lvalue_to_taint_mapt taint_algorithm_computing_summary_of_functiont::
10891132
break;
10901133
case FUNCTION_CALL:
10911134
{
1135+
TMPROF_BLOCK();
1136+
10921137
const code_function_callt &fn_call = to_code_function_call(I.code);
10931138
const exprt &callee_expr = fn_call.function();
10941139
if(callee_expr.id()==ID_symbol)
@@ -1155,6 +1200,8 @@ numbered_lvalue_to_taint_mapt taint_algorithm_computing_summary_of_functiont::
11551200
for(const taint_propagation_rulet &propagation_rule :
11561201
propagation_rules)
11571202
{
1203+
TMPROF_BLOCK();
1204+
11581205
const taint_sett taint_from_rule =
11591206
propagation_rule.has_input_condition()
11601207
? propagation_rule.apply(
@@ -1229,6 +1276,8 @@ numbered_lvalue_to_taint_mapt taint_algorithm_computing_summary_of_functiont::
12291276
}
12301277
for(const taint_sanitizer_rulet &sanitizer_rule : sanitizer_rules)
12311278
{
1279+
TMPROF_BLOCK();
1280+
12321281
const taintable_locationt &sanitized_location =
12331282
sanitizer_rule.get_sanitized_location();
12341283

@@ -1280,6 +1329,8 @@ numbered_lvalue_to_taint_mapt taint_algorithm_computing_summary_of_functiont::
12801329
}
12811330
for(const taint_sink_rulet &sink_rule : sink_rules)
12821331
{
1332+
TMPROF_BLOCK();
1333+
12831334
statistics->on_taint_analysis_apply_sink_rule(
12841335
sink_rule.get_id(), I.location_number);
12851336

@@ -1475,6 +1526,8 @@ void taint_algorithm_computing_summary_of_functiont::
14751526
taint_summaryt &summary,
14761527
const written_expressionst &written)
14771528
{
1529+
TMPROF_BLOCK();
1530+
14781531
taint_sett end_values_taint;
14791532
const numbered_lvalue_to_taint_mapt &end_value_taints =
14801533
summary.domain.at(std::prev(fn_to_summarise.body.instructions.cend()));
@@ -1537,6 +1590,8 @@ void taint_algorithm_computing_summary_of_functiont::
15371590
taint_summaryt::dbt &database,
15381591
local_value_set_analysist::dbt &lvsa_db)
15391592
{
1593+
TMPROF_BLOCK();
1594+
15401595
const goto_functionst::function_mapt &functions=
15411596
program->get_functions().function_map;
15421597
const auto fn_iter=functions.find(function_id);

src/util/tmprof.cpp

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
// Copyright 2018 Diffblue Limited. All Rights Reserved.
2+
3+
/// \file
4+
/// Micro time profiler with code block granularity.
5+
6+
#include <util/tmprof.h>
7+
#include <boost/filesystem.hpp>
8+
#include <iostream>
9+
#include <sstream>
10+
11+
static bool enabled = true;
12+
13+
bool is_time_profiling_enabled()
14+
{
15+
return enabled;
16+
}
17+
18+
void enable_time_profiling(const bool state)
19+
{
20+
enabled = state;
21+
}
22+
23+
std::list<tmprof_detail_datat> tmprof_detail_datat::records;
24+
25+
tmprof_detail_datat *
26+
tmprof_detail_datat::create(const char *name, const unsigned long line)
27+
{
28+
records.emplace_back(name, line);
29+
return &records.back();
30+
}
31+
32+
void tmprof_detail_datat::on_hit(const double duration)
33+
{
34+
total_time += duration;
35+
if(max_time < duration)
36+
max_time = duration;
37+
++hit_count;
38+
}
39+
40+
json_objectt tmprof_detail_datat::dump_as_json()
41+
{
42+
json_objectt root;
43+
for(const auto &record : records)
44+
if(record.get_hit_count() != 0ULL)
45+
{
46+
json_objectt table;
47+
table["total_time"] =
48+
json_numbert(std::to_string(record.get_total_time()));
49+
table["max_time"] = json_numbert(std::to_string(record.get_max_time()));
50+
table["hit_count"] = json_numbert(std::to_string(record.get_hit_count()));
51+
std::stringstream sstr;
52+
sstr << record.get_name() << " [" << record.get_line() << "]";
53+
root[sstr.str()] = table;
54+
}
55+
return root;
56+
}
57+
58+
void tmprof_dump_as_json(std::ostream &ostr)
59+
{
60+
ostr << tmprof_detail_datat::dump_as_json();
61+
}
62+
63+
void tmprof_dump_as_json(const boost::filesystem::path &out_file_pathname)
64+
{
65+
if(!boost::filesystem::exists(out_file_pathname.parent_path()))
66+
boost::filesystem::create_directory(out_file_pathname.parent_path());
67+
std::ofstream ostr(out_file_pathname.native());
68+
tmprof_dump_as_json(ostr);
69+
}

0 commit comments

Comments
 (0)