09e4739b0882aadc5f7cd5aa9d2aa01383fbeee2
[c11tester.git] / predicate.cc
1 #include "funcinst.h"
2 #include "predicate.h"
3 #include "concretepredicate.h"
4
5 Predicate::Predicate(FuncInst * func_inst, bool is_entry, bool is_exit) :
6         func_inst(func_inst),
7         entry_predicate(is_entry),
8         exit_predicate(is_exit),
9         does_write(false),
10         exploration_count(0),
11         failure_count(0),
12         pred_expressions(16),
13         children(),
14         parent(NULL),
15         exit(NULL),
16         backedges(16)
17 {}
18
19 Predicate::~Predicate()
20 {
21         // parent and func_inst should not be deleted
22         pred_expressions.reset();
23         backedges.reset();
24         children.clear();
25 }
26
27 unsigned int pred_expr_hash(struct pred_expr * expr)
28 {
29         return (unsigned int)((uintptr_t)expr);
30 }
31
32 bool pred_expr_equal(struct pred_expr * p1, struct pred_expr * p2)
33 {
34         if (p1->token != p2->token)
35                 return false;
36         if (p1->token == EQUALITY && p1->func_inst != p2->func_inst)
37                 return false;
38         if (p1->value != p2->value)
39                 return false;
40         return true;
41 }
42
43 void Predicate::add_predicate_expr(token_t token, FuncInst * func_inst, bool value)
44 {
45         struct pred_expr *ptr = new pred_expr(token, func_inst, value);
46         pred_expressions.add(ptr);
47 }
48
49 void Predicate::add_child(Predicate * child)
50 {
51         /* check duplication? */
52         children.push_back(child);
53 }
54
55 void Predicate::copy_predicate_expr(Predicate * other)
56 {
57         PredExprSet * other_pred_expressions = other->get_pred_expressions();
58         PredExprSetIter * it = other_pred_expressions->iterator();
59
60         while (it->hasNext()) {
61                 struct pred_expr * ptr = it->next();
62                 struct pred_expr * copy = new pred_expr(ptr->token, ptr->func_inst, ptr->value);
63                 pred_expressions.add(copy);
64         }
65 }
66
67 /* Evaluate predicate expressions against the given inst_act_map */
68 ConcretePredicate * Predicate::evaluate(inst_act_map_t * inst_act_map, thread_id_t tid)
69 {
70         ConcretePredicate * concrete = new ConcretePredicate(tid);
71         PredExprSetIter * it = pred_expressions.iterator();
72
73         while (it->hasNext()) {
74                 struct pred_expr * ptr = it->next();
75                 uint64_t value = 0;
76
77                 switch(ptr->token) {
78                         case NOPREDICATE:
79                                 break;
80                         case EQUALITY:
81                                 FuncInst * to_be_compared;
82                                 ModelAction * last_act;
83
84                                 to_be_compared = ptr->func_inst;
85                                 last_act = inst_act_map->get(to_be_compared);
86                                 value = last_act->get_reads_from_value();
87                                 break;
88                         case NULLITY:
89                                 break;
90                         default:
91                                 break;
92                 }
93
94                 concrete->add_expression(ptr->token, value, ptr->value);
95         }
96
97         return concrete;
98 }
99
100 void Predicate::print_predicate()
101 {
102         model_print("\"%p\" [shape=box, label=\"\n", this);
103         if (entry_predicate) {
104                 model_print("entry node\"];\n");
105                 return;
106         }
107
108         if (exit_predicate) {
109                 model_print("exit node\"];\n");
110                 return;
111         }
112
113         func_inst->print();
114
115         PredExprSetIter * it = pred_expressions.iterator();
116
117         if (pred_expressions.getSize() == 0)
118                 model_print("predicate unset\n");
119
120         while (it->hasNext()) {
121                 struct pred_expr * expr = it->next();
122                 FuncInst * inst = expr->func_inst;
123                 switch (expr->token) {
124                         case NOPREDICATE:
125                                 break;
126                         case EQUALITY:
127                                 model_print("predicate token: equality, position: %s, value: %d\n", inst->get_position(), expr->value);
128                                 break;
129                         case NULLITY:
130                                 model_print("predicate token: nullity, value: %d\n", expr->value);
131                                 break;
132                         default:
133                                 model_print("unknown predicate token\n");
134                                 break;
135                 }
136         }
137
138         if (does_write) {
139                 model_print("Does write\n");
140         }
141         model_print("Count: %d, failed count: %d\n", exploration_count, failure_count);
142         model_print("\"];\n");
143 }
144
145 void Predicate::print_pred_subtree()
146 {
147         print_predicate();
148         for (uint i = 0; i < children.size(); i++) {
149                 Predicate * child = children[i];
150                 child->print_pred_subtree();
151                 model_print("\"%p\" -> \"%p\"\n", this, child);
152         }
153
154         PredSetIter * it = backedges.iterator();
155         while (it->hasNext()) {
156                 Predicate * backedge = it->next();
157                 model_print("\"%p\" -> \"%p\"[style=dashed, color=grey]\n", this, backedge);
158         }
159
160         if (exit) {
161                 model_print("\"%p\" -> \"%p\"[style=dashed, color=red]\n", this, exit);
162         }
163 }