+/* Given curr_pred and next_inst, find the branch following curr_pred that
+ * contains next_inst and the correct predicate.
+ * @return true if branch found, false otherwise.
+ */
+bool FuncNode::follow_branch(Predicate ** curr_pred, FuncInst * next_inst, ModelAction * next_act,
+ HashTable<FuncInst *, ModelAction *, uintptr_t, 0> * inst_act_map,
+ SnapVector<Predicate *> * unset_predicates)
+{
+ /* check if a branch with func_inst and corresponding predicate exists */
+ bool branch_found = false;
+ ModelVector<Predicate *> * branches = (*curr_pred)->get_children();
+ for (uint i = 0; i < branches->size(); i++) {
+ Predicate * branch = (*branches)[i];
+ if (branch->get_func_inst() != next_inst)
+ continue;
+
+ /* check against predicate expressions */
+ bool predicate_correct = true;
+ PredExprSet * pred_expressions = branch->get_pred_expressions();
+ PredExprSetIter * pred_expr_it = pred_expressions->iterator();
+
+ if (pred_expressions->getSize() == 0) {
+ predicate_correct = false;
+ unset_predicates->push_back(branch);
+ }
+
+ while (pred_expr_it->hasNext()) {
+ pred_expr * pred_expression = pred_expr_it->next();
+ uint64_t last_read, next_read;
+ bool equality;
+
+ switch(pred_expression->token) {
+ case NOPREDICATE:
+ predicate_correct = true;
+ break;
+ case EQUALITY:
+ FuncInst * to_be_compared;
+ ModelAction * last_act;
+
+ to_be_compared = pred_expression->func_inst;
+ last_act = inst_act_map->get(to_be_compared);
+
+ last_read = last_act->get_reads_from_value();
+ next_read = next_act->get_reads_from_value();
+ equality = (last_read == next_read);
+ if (equality != pred_expression->value)
+ predicate_correct = false;
+
+ break;
+ case NULLITY:
+ next_read = next_act->get_reads_from_value();
+ equality = ((void*)next_read == NULL);
+ if (equality != pred_expression->value)
+ predicate_correct = false;
+ break;
+ default:
+ predicate_correct = false;
+ model_print("unkown predicate token\n");
+ break;
+ }
+ }
+
+ if (predicate_correct) {
+ *curr_pred = branch;
+ branch_found = true;
+ break;
+ }
+ }
+
+ return branch_found;
+}
+
+/* Able to generate complex predicates when there are multiple predciate expressions */
+void FuncNode::generate_predicate(Predicate ** curr_pred, FuncInst * next_inst,
+ SnapVector<struct half_pred_expr *> * half_pred_expressions)
+{
+ ASSERT(half_pred_expressions->size() != 0);
+ SnapVector<Predicate *> predicates;
+
+ struct half_pred_expr * half_expr = (*half_pred_expressions)[0];
+ predicates.push_back(new Predicate(next_inst));
+ predicates.push_back(new Predicate(next_inst));
+
+ predicates[0]->add_predicate_expr(half_expr->token, half_expr->func_inst, true);
+ predicates[1]->add_predicate_expr(half_expr->token, half_expr->func_inst, false);
+
+ for (uint i = 1; i < half_pred_expressions->size(); i++) {
+ half_expr = (*half_pred_expressions)[i];
+
+ uint old_size = predicates.size();
+ for (uint j = 0; j < old_size; j++) {
+ Predicate * pred = predicates[j];
+ Predicate * new_pred = new Predicate(next_inst);
+ new_pred->copy_predicate_expr(pred);
+
+ pred->add_predicate_expr(half_expr->token, half_expr->func_inst, true);
+ new_pred->add_predicate_expr(half_expr->token, half_expr->func_inst, false);
+
+ predicates.push_back(new_pred);
+ }
+ }
+
+ for (uint i = 0; i < predicates.size(); i++) {
+ Predicate * pred= predicates[i];
+ (*curr_pred)->add_child(pred);
+ pred->set_parent(*curr_pred);
+ }
+}
+
+/* Amend predicates that contain no predicate expressions. Currenlty only amend with NULLITY predicates */
+bool FuncNode::amend_predicate_expr(Predicate ** curr_pred, FuncInst * next_inst, ModelAction * next_act)
+{
+ // there should only be only child
+ Predicate * unset_pred = (*curr_pred)->get_children()->back();
+ uint64_t read_val = next_act->get_reads_from_value();
+
+ // only generate NULLITY predicate when it is actually NULL.
+ if ( !next_inst->is_single_location() && (void*)read_val == NULL ) {
+ Predicate * new_pred = new Predicate(next_inst);
+
+ (*curr_pred)->add_child(new_pred);
+ new_pred->set_parent(*curr_pred);
+
+ unset_pred->add_predicate_expr(NULLITY, NULL, false);
+ new_pred->add_predicate_expr(NULLITY, NULL, true);
+
+ return true;
+ }
+
+ return false;
+}
+
+void FuncNode::add_to_val_loc_map(uint64_t val, void * loc)
+{
+ loc_set_t * locations = val_loc_map->get(val);
+
+ if (locations == NULL) {
+ locations = new loc_set_t();
+ val_loc_map->put(val, locations);
+ }
+
+ update_loc_may_equal_map(loc, locations);
+ locations->add(loc);
+ // values_may_read_from->add(val);
+}
+
+void FuncNode::add_to_val_loc_map(value_set_t * values, void * loc)
+{
+ value_set_iter * it = values->iterator();
+ while (it->hasNext()) {
+ uint64_t val = it->next();
+ add_to_val_loc_map(val, loc);
+ }
+}
+
+void FuncNode::update_loc_may_equal_map(void * new_loc, loc_set_t * old_locations)
+{
+ loc_set_t * neighbors = loc_may_equal_map->get(new_loc);
+
+ if (neighbors == NULL) {
+ neighbors = new loc_set_t();
+ loc_may_equal_map->put(new_loc, neighbors);
+ }
+
+ loc_set_iter * loc_it = old_locations->iterator();
+ while (loc_it->hasNext()) {
+ // new_loc: { old_locations, ... }
+ void * member = loc_it->next();
+ neighbors->add(member);
+
+ // for each i in old_locations, i : { new_loc, ... }
+ loc_set_t * _neighbors = loc_may_equal_map->get(member);
+ if (_neighbors == NULL) {
+ _neighbors = new loc_set_t();
+ loc_may_equal_map->put(member, _neighbors);
+ }
+ _neighbors->add(new_loc);
+ }
+}
+
+void FuncNode::init_predicate_tree_position(thread_id_t tid)
+{
+ uint thread_id = id_to_int(tid);
+ if (predicate_tree_position.size() <= thread_id)
+ predicate_tree_position.resize(thread_id + 1);