#include "funcnode.h"
#include <fcntl.h>
-#include "common.h"
FuncNode::FuncNode() :
predicate_tree_initialized(false),
if (inst_list == NULL || inst_list->size() == 0)
return;
+/*
if (predicate_tree_initialized) {
return;
}
-
predicate_tree_initialized = true;
-
+*/
// maybe restrict the size of hashtable to save calloc time
- HashTable<void *, FuncInst *, uintptr_t, 4> loc_inst_map;
+ HashTable<void *, FuncInst *, uintptr_t, 4> loc_inst_map(64);
sllnode<FuncInst *> *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<Predicate *> * 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);
it = it->getNext();
}
- 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<Predicate *, uintptr_t, 0, model_malloc, model_calloc, model_free> * it;
- it = predicate_tree_entry.iterator();
+ PredSetIter * it = predicate_tree_entry.iterator();
while (it->hasNext()) {
Predicate * p = it->next();
typedef ModelList<FuncInst *> func_inst_list_mt;
typedef HashTable<void *, uint64_t, uintptr_t, 4, model_malloc, model_calloc, model_free> read_map_t;
+typedef HSIterator<Predicate *, uintptr_t, 0, model_malloc, model_calloc, model_free> PredSetIter;
class FuncNode {
public:
LinkNode<_Key> *next;
};
-template<typename _Key, typename _KeyInt, int _Shift, void *
- (* _malloc)(size_t), void * (* _calloc)(size_t, size_t), void (*_free)(void *), unsigned int (*hash_function
- )(_Key), bool (*equals)(_Key, _Key)>
+template<typename _Key, typename _KeyInt, int _Shift, void * (* _malloc)(size_t), void * (* _calloc)(size_t, size_t), void (*_free)(void *), unsigned int (*hash_function)(_Key), bool (*equals)(_Key, _Key)>
class HashSet;
template<typename _Key, typename _KeyInt, int _Shift, void * (* _malloc)(size_t), void * (* _calloc)(size_t, size_t), void (*_free)(void *), unsigned int (*hash_function)(_Key) = default_hash_function<_Key, _Shift, _KeyInt>, bool (*equals)(_Key, _Key) = default_equals<_Key> >
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;
/* 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];
Predicate::Predicate(FuncInst * func_inst) :
func_inst(func_inst),
- predicates(),
+ pred_expressions(),
children()
{}
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)
{
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()) {
unsigned int pred_expr_hash (struct pred_expr *);
bool pred_expr_equal(struct pred_expr *, struct pred_expr *);
-typedef HashSet<struct pred_expr *, uintptr_t, 0, model_malloc, model_calloc, model_free, pred_expr_hash, pred_expr_equal> PredSet;
-typedef HSIterator<struct pred_expr *, uintptr_t, 0, model_malloc, model_calloc, model_free, pred_expr_hash, pred_expr_equal> PredSetIter;
+typedef HashSet<struct pred_expr *, uintptr_t, 0, model_malloc, model_calloc, model_free, pred_expr_hash, pred_expr_equal> PredExprSet;
+typedef HSIterator<struct pred_expr *, uintptr_t, 0, model_malloc, model_calloc, model_free, pred_expr_hash, pred_expr_equal> PredExprSetIter;
typedef enum predicate_token {
EQUALITY, NULLITY
~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<Predicate *> * get_children() { return &children; }
void print_predicate();
void print_pred_subtree();
private:
FuncInst * func_inst;
/* may have multiple precicates */
- PredSet predicates;
+ PredExprSet pred_expressions;
ModelVector<Predicate *> children;
};