+/* Infer predicate expressions, which are generated in FuncNode::generate_predicates */
+void FuncNode::infer_predicates(FuncInst * next_inst, ModelAction * next_act,
+HashTable<void *, ModelAction *, uintptr_t, 0> * loc_act_map,
+SnapVector<struct half_pred_expr *> * half_pred_expressions)
+{
+ void * loc = next_act->get_location();
+
+ if (next_inst->is_read()) {
+ /* read + rmw */
+ if ( loc_act_map->contains(loc) ) {
+ ModelAction * last_act = loc_act_map->get(loc);
+ FuncInst * last_inst = get_inst(last_act);
+ struct half_pred_expr * expression = new half_pred_expr(EQUALITY, last_inst);
+ half_pred_expressions->push_back(expression);
+ } else if ( next_inst->is_single_location() ) {
+ loc_set_t * loc_may_equal = loc_may_equal_map->get(loc);
+
+ if (loc_may_equal != NULL) {
+ loc_set_iter * loc_it = loc_may_equal->iterator();
+ while (loc_it->hasNext()) {
+ void * neighbor = loc_it->next();
+ if (loc_act_map->contains(neighbor)) {
+ ModelAction * last_act = loc_act_map->get(neighbor);
+ FuncInst * last_inst = get_inst(last_act);
+
+ struct half_pred_expr * expression = new half_pred_expr(EQUALITY, last_inst);
+ half_pred_expressions->push_back(expression);
+ }
+ }
+ }
+ } else {
+ // next_inst is not single location
+ uint64_t read_val = next_act->get_reads_from_value();
+
+ // only infer NULLITY predicate when it is actually NULL.
+ if ( (void*)read_val == NULL) {
+ struct half_pred_expr * expression = new half_pred_expr(NULLITY, NULL);
+ half_pred_expressions->push_back(expression);
+ }
+ }
+ } else {
+ /* Pure writes */
+ // TODO: do anything here?
+ }
+}
+