23 {
"red",
"blue",
"black",
"green",
"yellow",
24 "orange",
"blueviolet",
"cyan",
"cadetblue",
"magenta",
"palegreen",
25 "deeppink",
"indigo",
"olivedrab"};
26#define print_colour(u) colour_map[u%NB_COLOURS]
29 std::set<event_idt> &visited)
32 file << node_id <<
"[label=\"" << node <<
", " << node.
source_location <<
34 visited.insert(node_id);
36 for(wmm_grapht::edgest::const_iterator
37 it=
po_out(node_id).begin();
38 it!=
po_out(node_id).end(); ++it)
40 file << node_id <<
"->" << it->first <<
"[]\n";
41 file <<
"{rank=same; " << node_id <<
"; " << it->first <<
"}\n";
42 if(visited.find(it->first)==visited.end())
46 for(wmm_grapht::edgest::const_iterator
48 it!=
com_out(node_id).end(); ++it)
50 file << node_id <<
"->" << it->first <<
"[style=\"dotted\"]\n";
51 if(visited.find(it->first)==visited.end())
59 std::set<event_idt> visited;
62 file.open(
"graph.dot");
63 file <<
"digraph G {\n";
64 file <<
"rankdir=LR;\n";
85 for(wmm_grapht::edgest::const_iterator it=
po_out(begin).begin();
112 std::set<event_idt> covered;
124 std::map<event_idt, event_idt>
orig2copy;
127 for(std::set<event_idt>::const_iterator it=covered.begin();
141 for(std::set<event_idt>::const_iterator
it_i=covered.begin();
145 for(std::set<event_idt>::const_iterator
it_j=covered.begin();
163 for(std::set<event_idt>::const_iterator
it_i=covered.begin();
261 if(
BC_it==begin() && egraph[back()].thread==first.
thread)
291 unsigned thread=egraph[*begin()].thread;
295 thread=egraph[*
th_it].thread;
303 for(; it!=end() && next!=end(); ++next, ++it)
351 if(check_AC(
s_it, first, second))
354 if(check_BC(it, first, second))
396 unsafe_pairs.insert(
delay);
438 unsafe_pairs.insert(
delay);
483 if(check_AC(
s_it, first, second))
486 if(check_BC(begin(), first, second))
518 unsafe_pairs.insert(
delay);
552 unsafe_pairs.insert(
delay);
576 unsigned thread=egraph[*begin()].thread;
580 thread=egraph[*
th_it].thread;
644 && egraph[*
AC_it].is_cumul()
645 && egraph[*
AC_it].is_corresponding_fence(egraph[*it], egraph[*
s_it]))
654 if(
AC_it==end() && egraph[front()].thread==second.
thread)
660 egraph[*
AC_it].is_cumul() &&
661 egraph[*
AC_it].is_corresponding_fence(egraph[*it], egraph[*
s_it]))
688 egraph[*
BC_it].is_cumul() &&
689 egraph[*
BC_it].is_corresponding_fence(egraph[*it], egraph[*
s_it]))
699 if(
BC_it==begin() && egraph[back()].thread==first.
thread)
705 egraph[*
BC_it].is_cumul() &&
706 egraph[*
BC_it].is_corresponding_fence(egraph[*it], egraph[*
s_it]))
730 unsafe_pairs.insert(
delay);
748 unsafe_pairs.insert(
delay);
799 && egraph[*
AC_it].is_cumul()
800 && egraph[*
AC_it].is_corresponding_fence(first, second))
809 if(
AC_it==end() && egraph[front()].thread==second.
thread)
815 egraph[*
AC_it].is_cumul() &&
816 egraph[*
AC_it].is_corresponding_fence(first, second))
834 && egraph[*
BC_it].is_cumul()
835 && egraph[*
BC_it].is_corresponding_fence(first, second))
844 if(
BC_it==begin() && egraph[back()].thread==first.
thread)
852 && egraph[*
BC_it].is_cumul()
853 && egraph[*
BC_it].is_corresponding_fence(first, second))
873 unsafe_pairs.insert(
delay);
887 unsafe_pairs.insert(
delay);
901 for(; it!=end(); ++it)
914 const irep_idt &var=egraph[*it].variable;
918 if(!egraph.ignore_arrays &&
id2string(var).find(
"[]")!=std::string::npos)
921 for(; it!=end(); ++it)
939 for(; it!=end(); it++)
952 const irep_idt &var=egraph[*it].variable;
955 for(; it!=end();
prev=it, ++it)
996 if(
dep.dp(current, next))
1013 if(
dep.dp(current, next))
1021 std::string
cycle=
"Cycle: ";
1023 cycle += std::to_string(egraph[*it].
id) +
"; ";
1024 return cycle +
" End of cycle.";
1029 std::string name=
"Unsafe pairs: ";
1030 for(std::set<delayt>::const_iterator it=unsafe_pairs.begin();
1031 it!=unsafe_pairs.end();
1076 std::string
cycle=
"Cycle: ";
1083 return cycle+
" End of cycle.";
1094 cycle +=
" thread " + std::to_string(
it_evt.thread) +
") ";
1101 std::map<std::string, std::string> &
map_id2var,
1102 std::map<std::string, std::string> &
map_var2id)
const
1109 +
" (" +
it_evt.source_location.as_string() +
")";
1112 cycle +=
"t" + std::to_string(
it_evt.thread) +
" (";
1120 cycle +=
"t" + std::to_string(
it_evt.thread) +
" (";
1129 std::map<std::string, std::string> &
map_id2var,
1130 std::map<std::string, std::string> &
map_var2id,
1131 bool hide_internals)
const
1141 this->hide_internals(
reduced);
1151 cycle+=print_name(*
this, model);
1288 "operation is read or write");
1289 name += (model==
Power?
" Sync":
" MFence");
1317 cand.fence_value()&1))
1328 "operation is read or write");
1361 cand.fence_value()&1))
1372 "operation is read or write");
1437 for(std::string::const_iterator it=name.begin();
1454 "operation is not a fence");
1462 for( ; it!=
reduced.end(); ++it)
1472 cand.fence_value()&1))
1480 "operation is read or write");
1518 dep.dp(last, first))
1537 for(std::string::const_iterator it=name.begin();
1559 str <<
"/* " <<
id <<
" */\n";
1562 str <<
ev.id <<
"[label=\"\\\\lb {" <<
ev.id <<
"}" <<
ev.get_operation();
1563 str <<
"{" <<
ev.variable <<
"} {} @thread" <<
ev.thread <<
"\"];\n";
1573 str <<
"/* " <<
id <<
" */\n";
1580 str <<
prev.id <<
"->";
1586 n_it!=end() ? egraph[*
n_it] : egraph[front()];
1587 str << succ.
id <<
"[label=\"";
1588 str << (model==
Power?
"Sync":
"MFence");
1597 n_it!=end() ? egraph[*
n_it] : egraph[front()];
1598 str << succ.
id <<
"[label=\"";
1599 str <<
"LwSync" << (
prev.variable==cur.
variable?
"s":
"d");
1606 str << cur.
id <<
"[label=\"";
1607 str <<
"Rf" << (
prev.thread==cur.
thread?
"i":
"e");
1613 str << cur.
id <<
"[label=\"";
1614 str <<
"Fr" << (
prev.thread==cur.
thread?
"i":
"e");
1622 str << cur.
id <<
"[label=\"";
1623 str <<
"Ws" << (
prev.thread==cur.
thread?
"i":
"e");
1628 str << cur.
id <<
"[label=\"";
1633 str << cur.
id <<
"[label=\"?";
1645 str <<
"/* " <<
id <<
" */\n";
1648 str << last.
id <<
"->";
1654 str << succ.
id <<
"[label=\"";
1655 str << (model==
Power?
"Sync":
"MFence");
1664 str << succ.
id <<
"[label=\"";
1672 str << first.
id <<
"[label=\"";
1679 str << first.
id <<
"[label=\"";
1688 str << first.
id <<
"[label=\"";
1694 str << first.
id <<
"[label=\"";
1699 str << first.
id <<
"[label=\"?";
bool unsafe_pair(const abstract_eventt &next, memory_modelt model) const
std::string get_operation() const
bool unsafe_pair_lwfence(const abstract_eventt &next, memory_modelt model) const
source_locationt source_location
bool unsafe_pair_asm(const abstract_eventt &next, memory_modelt model, unsigned char met) const
unsigned char fence_value() const
ait supplies three of the four components needed: an abstract interpreter (in this case handling func...
bool dp(const abstract_eventt &e1, const abstract_eventt &e2) const
search in N^2
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
std::string print_events() const
void hide_internals(critical_cyclet &reduced) const
data_typet::const_iterator const_iterator
std::string print_unsafes() const
bool is_unsafe(memory_modelt model, bool fast=false)
checks whether there is at least one pair which is unsafe (takes fences and dependencies into account...
bool is_unsafe_asm(memory_modelt model, bool fast=false)
same as is_unsafe, but with ASM fences
bool check_AC(data_typet::const_iterator s_it, const abstract_eventt &first, const abstract_eventt &second) const
bool is_not_uniproc() const
bool is_not_weak_uniproc() const
std::string print_name(const critical_cyclet &redyced, memory_modelt model) const
std::string print_all(memory_modelt model, std::map< std::string, std::string > &map_id2var, std::map< std::string, std::string > &map_var2id, bool hide_internals) const
bool check_BC(data_typet::const_iterator it, const abstract_eventt &first, const abstract_eventt &second) const
void print_dot(std::ostream &str, unsigned colour, memory_modelt model) const
std::string print_detail(const critical_cyclet &reduced, std::map< std::string, std::string > &map_id2var, std::map< std::string, std::string > &map_var2id) const
bool is_not_thin_air() const
std::string print_output() const
std::string print() const
grapht< abstract_eventt >::nodet & operator[](event_idt n)
bool has_com_edge(event_idt i, event_idt j) const
std::list< event_idt > po_order
void explore_copy_segment(std::set< event_idt > &explored, event_idt begin, event_idt end) const
copies the segment
event_idt copy_segment(event_idt begin, event_idt end)
bool has_po_edge(event_idt i, event_idt j) const
const wmm_grapht::edgest & po_out(event_idt n) const
std::set< std::pair< const abstract_eventt &, const abstract_eventt & > > duplicated_bodies
void add_com_edge(event_idt a, event_idt b)
const wmm_grapht::edgest & com_out(event_idt n) const
void add_po_edge(event_idt a, event_idt b)
void print_rec_graph(std::ofstream &file, event_idt node_id, std::set< event_idt > &visited)
mstreamt & status() const
static const char * colour_map[14]
wmm_grapht::node_indext event_idt
const std::string & id2string(const irep_idt &d)
#define CHECK_RETURN(CONDITION)
#define UNREACHABLE
This should be used to mark dead code.
#define DATA_INVARIANT(CONDITION, REASON)
This condition should be used to document that assumptions that are made on goto_functions,...
#define PRECONDITION(CONDITION)
#define INVARIANT(CONDITION, REASON)
This macro uses the wrapper function 'invariant_violated_string'.