5 predicate_tree_initialized(false),
10 predicate_tree_entry()
13 /* Check whether FuncInst with the same type, position, and location
14 * as act has been added to func_inst_map or not. If so, return it;
15 * if not, add it and return it.
17 * @return FuncInst with the same type, position, and location as act */
18 FuncInst * FuncNode::get_or_add_inst(ModelAction *act)
21 const char * position = act->get_position();
23 /* THREAD* actions, ATOMIC_LOCK, ATOMIC_TRYLOCK, and ATOMIC_UNLOCK
24 * actions are not tagged with their source line numbers
29 if ( func_inst_map.contains(position) ) {
30 FuncInst * inst = func_inst_map.get(position);
32 if (inst->get_type() != act->get_type() ) {
33 // model_print("action with a different type occurs at line number %s\n", position);
34 FuncInst * func_inst = inst->search_in_collision(act);
36 if (func_inst != NULL) {
37 // return the FuncInst found in the collision list
41 func_inst = new FuncInst(act, this);
42 inst->get_collisions()->push_back(func_inst);
43 inst_list.push_back(func_inst); // delete?
51 FuncInst * func_inst = new FuncInst(act, this);
53 func_inst_map.put(position, func_inst);
54 inst_list.push_back(func_inst);
59 void FuncNode::add_entry_inst(FuncInst * inst)
64 mllnode<FuncInst *> * it;
65 for (it = entry_insts.begin(); it != NULL; it = it->getNext()) {
66 if (inst == it->getVal())
70 entry_insts.push_back(inst);
74 * @brief Convert ModelAdtion list to FuncInst list
75 * @param act_list A list of ModelActions
77 void FuncNode::update_tree(action_list_t * act_list)
81 else if (act_list->size() == 0)
84 /* build inst_list from act_list for later processing */
85 func_inst_list_t inst_list;
86 func_inst_list_t read_inst_list;
87 HashTable<FuncInst *, uint64_t, uintptr_t, 4> read_val_map;
89 for (sllnode<ModelAction *> * it = act_list->begin(); it != NULL; it = it->getNext()) {
90 ModelAction * act = it->getVal();
91 FuncInst * func_inst = get_or_add_inst(act);
93 if (func_inst == NULL)
96 inst_list.push_back(func_inst);
98 /* if (!predicate_tree_initialized) {
99 model_print("position: %s ", act->get_position());
104 if (func_inst->is_read()) {
105 read_inst_list.push_back(func_inst);
106 read_val_map.put(func_inst, act->get_reads_from_value());
110 update_inst_tree(&inst_list);
111 init_predicate_tree(&read_inst_list, &read_val_map);
115 * @brief Link FuncInsts in inst_list - add one FuncInst to another's predecessors and successors
116 * @param inst_list A list of FuncInsts
118 void FuncNode::update_inst_tree(func_inst_list_t * inst_list)
120 if (inst_list == NULL)
122 else if (inst_list->size() == 0)
126 sllnode<FuncInst *>* it = inst_list->begin();
127 sllnode<FuncInst *>* prev;
129 /* add the first instruction to the list of entry insts */
130 FuncInst * entry_inst = it->getVal();
131 add_entry_inst(entry_inst);
135 prev = it->getPrev();
137 FuncInst * prev_inst = prev->getVal();
138 FuncInst * curr_inst = it->getVal();
140 prev_inst->add_succ(curr_inst);
141 curr_inst->add_pred(prev_inst);
147 /* @param tid thread id
148 * Store the values read by atomic read actions into thrd_read_map */
149 void FuncNode::store_read(ModelAction * act, uint32_t tid)
153 void * location = act->get_location();
154 uint64_t read_from_val = act->get_reads_from_value();
156 /* resize and initialize */
157 uint32_t old_size = thrd_read_map.size();
158 if (old_size <= tid) {
159 thrd_read_map.resize(tid + 1);
160 for (uint32_t i = old_size; i < tid + 1;i++)
161 thrd_read_map[i] = new read_map_t();
164 read_map_t * read_map = thrd_read_map[tid];
165 read_map->put(location, read_from_val);
167 /* Store the memory locations where atomic reads happen */
168 // read_locations.add(location);
171 uint64_t FuncNode::query_last_read(void * location, uint32_t tid)
173 if (thrd_read_map.size() <= tid)
176 read_map_t * read_map = thrd_read_map[tid];
178 /* last read value not found */
179 if ( !read_map->contains(location) )
182 uint64_t read_val = read_map->get(location);
186 /* @param tid thread id
187 * Reset read map for a thread. This function shall only be called
188 * when a thread exits a function
190 void FuncNode::clear_read_map(uint32_t tid)
192 if (thrd_read_map.size() <= tid)
195 thrd_read_map[tid]->reset();
198 void FuncNode::init_predicate_tree(func_inst_list_t * inst_list, HashTable<FuncInst *, uint64_t, uintptr_t, 4> * read_val_map)
200 if (inst_list == NULL || inst_list->size() == 0)
204 if (predicate_tree_initialized) {
207 predicate_tree_initialized = true;
209 // maybe restrict the size of hashtable to save calloc time
210 HashTable<void *, FuncInst *, uintptr_t, 4> loc_inst_map(64);
212 sllnode<FuncInst *> *it = inst_list->begin();
213 FuncInst * entry_inst = it->getVal();
215 /* get the unique Predicate pointer, assuming entry instructions have no predicate expression */
216 Predicate * curr_pred = NULL;
217 PredSetIter * pit = predicate_tree_entry.iterator();
218 while (pit->hasNext()) {
219 Predicate * p = pit->next();
220 p->get_func_inst()->print();
221 if (p->get_func_inst() == entry_inst) {
226 if (curr_pred == NULL) {
227 curr_pred = new Predicate(entry_inst);
228 predicate_tree_entry.add(curr_pred);
231 loc_inst_map.put(entry_inst->get_location(), entry_inst);
235 FuncInst * curr_inst = it->getVal();
236 bool child_found = false;
238 /* check if a child with the same func_inst and corresponding predicate exists */
239 ModelVector<Predicate *> * children = curr_pred->get_children();
240 for (uint i = 0; i < children->size(); i++) {
241 Predicate * child = (*children)[i];
242 if (child->get_func_inst() != curr_inst)
245 PredExprSet * pred_expressions = child->get_pred_expressions();
247 /* no predicate, follow the only child */
248 if (pred_expressions->getSize() == 0) {
249 model_print("no predicate exists: ");
258 if ( loc_inst_map.contains(curr_inst->get_location()) ) {
259 Predicate * new_pred1 = new Predicate(curr_inst);
260 new_pred1->add_predicate(EQUALITY, curr_inst->get_location(), true);
262 Predicate * new_pred2 = new Predicate(curr_inst);
263 new_pred2->add_predicate(EQUALITY, curr_inst->get_location(), false);
265 curr_pred->add_child(new_pred1);
266 curr_pred->add_child(new_pred2);
268 FuncInst * last_inst = loc_inst_map.get(curr_inst->get_location());
269 uint64_t last_read = read_val_map->get(last_inst);
270 if ( last_read == read_val_map->get(curr_inst) )
271 curr_pred = new_pred1;
273 curr_pred = new_pred2;
275 Predicate * new_pred = new Predicate(curr_inst);
276 curr_pred->add_child(new_pred);
277 curr_pred = new_pred;
281 loc_inst_map.put(curr_inst->get_location(), curr_inst);
286 // model_print("function %s\n", func_name);
287 // print_predicate_tree();
291 void FuncNode::print_predicate_tree()
293 model_print("digraph function_%s {\n", func_name);
294 PredSetIter * it = predicate_tree_entry.iterator();
296 while (it->hasNext()) {
297 Predicate * p = it->next();
298 p->print_pred_subtree();
300 model_print("}\n"); // end of graph
303 /* @param tid thread id
304 * Print the values read by the last read actions for each memory location
307 void FuncNode::print_last_read(uint32_t tid)
309 ASSERT(thrd_read_map.size() > tid);
310 read_map_t * read_map = thrd_read_map[tid];
312 mllnode<void *> * it;
313 for (it = read_locations.begin();it != NULL;it=it->getNext()) {
314 if ( !read_map->contains(it->getVal()) )
317 uint64_t read_val = read_map->get(it->getVal());
318 model_print("last read of thread %d at %p: 0x%x\n", tid, it->getVal(), read_val);