From: weiyu Date: Tue, 6 Aug 2019 00:28:10 +0000 (-0700) Subject: toward updating predicate trees every time a function exits X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=7569713765d10fb4ce7fa3bbd7b9b60956e69b44;p=c11tester.git toward updating predicate trees every time a function exits --- diff --git a/funcnode.cc b/funcnode.cc index c24449ff..44c69e22 100644 --- a/funcnode.cc +++ b/funcnode.cc @@ -1,6 +1,5 @@ #include "funcnode.h" #include -#include "common.h" FuncNode::FuncNode() : predicate_tree_initialized(false), @@ -201,47 +200,82 @@ void FuncNode::init_predicate_tree(func_inst_list_t * inst_list, HashTablesize() == 0) return; +/* if (predicate_tree_initialized) { return; } - predicate_tree_initialized = true; - +*/ // maybe restrict the size of hashtable to save calloc time - HashTable loc_inst_map; + HashTable loc_inst_map(64); sllnode *it = inst_list->begin(); FuncInst * entry_inst = it->getVal(); - /* entry instruction has no predicate expression */ - Predicate * curr_pred = new Predicate(entry_inst); - predicate_tree_entry.add(curr_pred); + /* get the unique Predicate pointer, assuming entry instructions have no predicate expression */ + Predicate * curr_pred = NULL; + PredSetIter * pit = predicate_tree_entry.iterator(); + while (pit->hasNext()) { + Predicate * p = pit->next(); + p->get_func_inst()->print(); + if (p->get_func_inst() == entry_inst) { + curr_pred = p; + break; + } + } + if (curr_pred == NULL) { + curr_pred = new Predicate(entry_inst); + predicate_tree_entry.add(curr_pred); + } + loc_inst_map.put(entry_inst->get_location(), entry_inst); it = it->getNext(); while (it != NULL) { FuncInst * curr_inst = it->getVal(); - if ( loc_inst_map.contains(curr_inst->get_location()) ) { - Predicate * new_pred1 = new Predicate(curr_inst); - new_pred1->add_predicate(EQUALITY, curr_inst->get_location(), true); - - Predicate * new_pred2 = new Predicate(curr_inst); - new_pred2->add_predicate(EQUALITY, curr_inst->get_location(), false); - - curr_pred->add_child(new_pred1); - curr_pred->add_child(new_pred2); - - FuncInst * last_inst = loc_inst_map.get(curr_inst->get_location()); - - uint64_t last_read = read_val_map->get(last_inst); - if ( last_read == read_val_map->get(curr_inst) ) - curr_pred = new_pred1; - else - curr_pred = new_pred2; - } else { - Predicate * new_pred = new Predicate(curr_inst); - curr_pred->add_child(new_pred); - curr_pred = new_pred; + bool child_found = false; + + /* check if a child with the same func_inst and corresponding predicate exists */ + ModelVector * children = curr_pred->get_children(); + for (uint i = 0; i < children->size(); i++) { + Predicate * child = (*children)[i]; + if (child->get_func_inst() != curr_inst) + continue; + + PredExprSet * pred_expressions = child->get_pred_expressions(); + + /* no predicate, follow the only child */ + if (pred_expressions->getSize() == 0) { + model_print("no predicate exists: "); + curr_inst->print(); + curr_pred = child; + child_found = true; + break; + } + } + + if (!child_found) { + if ( loc_inst_map.contains(curr_inst->get_location()) ) { + Predicate * new_pred1 = new Predicate(curr_inst); + new_pred1->add_predicate(EQUALITY, curr_inst->get_location(), true); + + Predicate * new_pred2 = new Predicate(curr_inst); + new_pred2->add_predicate(EQUALITY, curr_inst->get_location(), false); + + curr_pred->add_child(new_pred1); + curr_pred->add_child(new_pred2); + + FuncInst * last_inst = loc_inst_map.get(curr_inst->get_location()); + uint64_t last_read = read_val_map->get(last_inst); + if ( last_read == read_val_map->get(curr_inst) ) + curr_pred = new_pred1; + else + curr_pred = new_pred2; + } else { + Predicate * new_pred = new Predicate(curr_inst); + curr_pred->add_child(new_pred); + curr_pred = new_pred; + } } loc_inst_map.put(curr_inst->get_location(), curr_inst); @@ -249,16 +283,15 @@ void FuncNode::init_predicate_tree(func_inst_list_t * inst_list, HashTablegetNext(); } - model_print("function %s\n", func_name); - print_predicate_tree(); +// model_print("function %s\n", func_name); +// print_predicate_tree(); } void FuncNode::print_predicate_tree() { model_print("digraph function_%s {\n", func_name); - HSIterator * it; - it = predicate_tree_entry.iterator(); + PredSetIter * it = predicate_tree_entry.iterator(); while (it->hasNext()) { Predicate * p = it->next(); diff --git a/funcnode.h b/funcnode.h index 61ab0593..a4412c6c 100644 --- a/funcnode.h +++ b/funcnode.h @@ -9,6 +9,7 @@ typedef ModelList func_inst_list_mt; typedef HashTable read_map_t; +typedef HSIterator PredSetIter; class FuncNode { public: diff --git a/hashset.h b/hashset.h index 7f7febc6..baf6d43e 100644 --- a/hashset.h +++ b/hashset.h @@ -18,9 +18,7 @@ struct LinkNode { LinkNode<_Key> *next; }; -template +template class HashSet; template, bool (*equals)(_Key, _Key) = default_equals<_Key> > diff --git a/history.cc b/history.cc index 782da5a3..db5cbcac 100644 --- a/history.cc +++ b/history.cc @@ -113,9 +113,8 @@ void ModelHistory::process_action(ModelAction *act, thread_id_t tid) resize_func_nodes( func_id + 1 ); FuncNode * func_node = func_nodes[func_id]; - ASSERT (func_node != NULL); - /* do not care actions without a position */ + /* do not care about actions without a position */ if (act->get_position() == NULL) return; @@ -129,7 +128,7 @@ void ModelHistory::process_action(ModelAction *act, thread_id_t tid) /* return the FuncNode given its func_id */ FuncNode * ModelHistory::get_func_node(uint32_t func_id) { - if (func_nodes.size() <= func_id) // this node has not been added + if (func_nodes.size() <= func_id) // this node has not been added to func_nodes return NULL; return func_nodes[func_id]; diff --git a/predicate.cc b/predicate.cc index 42c63100..a5693c9b 100644 --- a/predicate.cc +++ b/predicate.cc @@ -2,7 +2,7 @@ Predicate::Predicate(FuncInst * func_inst) : func_inst(func_inst), - predicates(), + pred_expressions(), children() {} @@ -25,7 +25,7 @@ bool pred_expr_equal(struct pred_expr * p1, struct pred_expr * p2) void Predicate::add_predicate(token_t token, void * location, bool value) { struct pred_expr *ptr = new pred_expr(token, location, value); - predicates.add(ptr); + pred_expressions.add(ptr); } void Predicate::add_child(Predicate * child) @@ -38,9 +38,9 @@ void Predicate::print_predicate() { model_print("\"%p\" [shape=box, label=\"%p\n", this, this); func_inst->print(); - PredSetIter * it = predicates.iterator(); + PredExprSetIter * it = pred_expressions.iterator(); - if (predicates.getSize() == 0) + if (pred_expressions.getSize() == 0) model_print("no predicate\n"); while (it->hasNext()) { diff --git a/predicate.h b/predicate.h index 6d0dbc4b..3dfb8d5b 100644 --- a/predicate.h +++ b/predicate.h @@ -6,8 +6,8 @@ unsigned int pred_expr_hash (struct pred_expr *); bool pred_expr_equal(struct pred_expr *, struct pred_expr *); -typedef HashSet PredSet; -typedef HSIterator PredSetIter; +typedef HashSet PredExprSet; +typedef HSIterator PredExprSetIter; typedef enum predicate_token { EQUALITY, NULLITY @@ -38,9 +38,10 @@ public: ~Predicate(); FuncInst * get_func_inst() { return func_inst; } - PredSet * get_predicates() { return &predicates; } + PredExprSet * get_pred_expressions() { return &pred_expressions; } void add_predicate(token_t token, void * location, bool value); void add_child(Predicate * child); + ModelVector * get_children() { return &children; } void print_predicate(); void print_pred_subtree(); @@ -49,7 +50,7 @@ public: private: FuncInst * func_inst; /* may have multiple precicates */ - PredSet predicates; + PredExprSet pred_expressions; ModelVector children; };