Skip to content

Commit

Permalink
expand the data-flow analysis framework to union field analysis
Browse files Browse the repository at this point in the history
1) add another type of fact, the union field that is last written into, to the framework
2) use this kind of fact to avoid reading padding bits of union fields (an unspecified value)
3) cleanup and streamline the current framework so that more type of facts can be analyzed with less trouble in the future
4) extend the effect analysis to union variables
5) increase the chance of having more struct and unions, and the chance of having struct and char* as union field
5) fix some gcc warnings
6) remove some unused code, rename some functions to more meaningful names
7) make code more debugable
  • Loading branch information
Xuejun Yang committed Jun 17, 2011
1 parent 4cb9161 commit 3b31bff
Show file tree
Hide file tree
Showing 50 changed files with 843 additions and 431 deletions.
15 changes: 9 additions & 6 deletions src/Block.cpp
Expand Up @@ -103,9 +103,8 @@ Block::make_random(CGContext &cg_context, bool looping)
Function *curr_func = cg_context.get_current_func();
assert(curr_func);

Block *b = new Block(CGOptions::max_block_size());
Block *b = new Block(cg_context.get_current_block(), CGOptions::max_block_size());
b->func = curr_func;
b->parent = cg_context.get_current_block();
b->looping = looping;
// if there are induction variables, we are in a loop that traverses array(s)
b->in_array_loop = !(cg_context.iv_bounds.empty());
Expand All @@ -129,6 +128,8 @@ Block::make_random(CGContext &cg_context, bool looping)
return NULL;
}
unsigned int i;
if (b->stm_id == 1)
BREAK_NOP; // for debugging
for (i = 0; i <= max; ++i) {
Statement *s = Statement::make_random(cg_context);
// In the exhaustive mode, Statement::make_random could return NULL;
Expand Down Expand Up @@ -178,8 +179,8 @@ Block::make_random(CGContext &cg_context, bool looping)
/*
*
*/
Block::Block(int block_size)
: Statement(eBlock),
Block::Block(Block* b, int block_size)
: Statement(eBlock, b),
need_revisit(false),
depth_protect(false),
block_size_(block_size)
Expand Down Expand Up @@ -503,7 +504,6 @@ bool
Block::visit_facts(vector<const Fact*>& inputs, CGContext& cg_context) const
{
int dummy;
//static int g = 0;
FactMgr* fm = get_fact_mgr(&cg_context);
vector<const Fact*> dummy_facts;
Effect pre_effect = cg_context.get_accum_effect();
Expand Down Expand Up @@ -556,6 +556,7 @@ Block::find_fixed_point(vector<const Fact*> inputs, vector<const Fact*>& post_fa
FactMgr* fm = get_fact_mgr(&cg_context);
// include outputs from all back edges leading to this block
size_t i;
static int g = 0;
vector<const CFGEdge*> edges;
int cnt = 0;
do {
Expand Down Expand Up @@ -587,7 +588,9 @@ Block::find_fixed_point(vector<const Fact*> inputs, vector<const Fact*>& post_fa

// revisit statements with new inputs
for (i=0; i<stms.size(); i++) {
//int hh = g++;
int h = g++;
if (h == 2585)
BREAK_NOP; // for debugging
if (!stms[i]->analyze_with_edges_in(outputs, cg_context)) {
fail_index = i;
return false;
Expand Down
3 changes: 1 addition & 2 deletions src/Block.h
Expand Up @@ -64,8 +64,7 @@ class Block : public Statement
// Factory method.
static Block *make_random(CGContext &cg_context, bool looping = false);


Block(int block_size);
Block(Block* b, int block_size);
virtual ~Block(void);

//
Expand Down
4 changes: 4 additions & 0 deletions src/CGContext.cpp
Expand Up @@ -39,6 +39,7 @@
#include "Fact.h"
#include "FactMgr.h"
#include "FactPointTo.h"
#include "FactUnion.h"
#include "Lhs.h"
#include "Statement.h"
#include "Bookkeeper.h"
Expand Down Expand Up @@ -200,6 +201,9 @@ CGContext::read_var(const Variable *v)
bool
CGContext::check_read_var(const Variable *v, const std::vector<const Fact*>& facts)
{
if (v->is_union_field() && FactUnion::is_nonreadable_field(v, facts)) {
return false;
}
if (!read_indices(v, facts)) {
return false;
}
Expand Down
2 changes: 1 addition & 1 deletion src/CGOptions.cpp
Expand Up @@ -182,7 +182,7 @@ CGOptions::set_default_settings(void)
max_exhaustive_depth(CGOPTIONS_DEFAULT_MAX_EXHAUSTIVE_DEPTH);
max_indirect_level(CGOPTIONS_DEFAULT_MAX_INDIRECT_LEVEL);
output_file(CGOPTIONS_DEFAULT_OUTPUT_FILE);
interested_facts(ePointTo);
interested_facts(ePointTo | eUnionWrite);
allow_const_volatile(true);
avoid_signed_overflow(true);
CGOptions::paranoid(false);
Expand Down
21 changes: 19 additions & 2 deletions src/Effect.cpp
Expand Up @@ -288,8 +288,11 @@ Effect::is_read(const Variable *v) const
return true;
}
}
// if we read a struct/union, presumingly all the fields are read too
if (v->isFieldVarOf_) {
// if we read a struct, presumingly all the fields are read too
// however we can not say the same thing for unions: reading a particular
// unions field can cause unspecified behaviors, while reading the whole
// union won't
if (v->isFieldVarOf_ && v->isFieldVarOf_->type->eType == eStruct) {
return is_read(v->isFieldVarOf_);
}
return false;
Expand Down Expand Up @@ -605,6 +608,20 @@ Effect::has_global_effect(void) const
return false;
}

/*
* whether any field of an union is been read
*/
bool
Effect::union_field_is_read(void) const
{
for (size_t i=0; i<read_vars.size(); i++) {
if (read_vars[i]->is_union_field()) {
return true;
}
}
return false;
}

///////////////////////////////////////////////////////////////////////////////

// Local Variables:
Expand Down
1 change: 1 addition & 0 deletions src/Effect.h
Expand Up @@ -69,6 +69,7 @@ class Effect
bool sibling_field_is_written(const Variable *v) const;
bool is_read_partially(const Variable* v) const;
bool is_written_partially(const Variable* v) const;
bool union_field_is_read(void) const;
bool has_race_with(const Effect &e) const;
bool is_empty(void) const;
void consolidate(void);
Expand Down
18 changes: 2 additions & 16 deletions src/Expression.cpp
Expand Up @@ -199,8 +199,8 @@ ParamExpressionFilter::filter(int v) const
return true;
}
if (tt == eFunction) {
if (type_->eType == eStruct && !CGOptions::return_structs() ||
type_->eType == eUnion && !CGOptions::return_unions())
if ((type_->eType == eStruct && !CGOptions::return_structs()) ||
(type_->eType == eUnion && !CGOptions::return_unions()))
return true;
}
return false;
Expand Down Expand Up @@ -228,20 +228,6 @@ ExpressionTypeProbability(const CGContext &cg_context, const ExpressionFilter *f
return filter->number_to_termtype(i, Expression::exprTable_);
}

/*
*
*/
static eTermType
ParameterTypeProbability(const CGContext &cg_context)
{
if (cg_context.expr_depth > CGOptions::max_expr_depth())
return eVariable;

int i = rnd_upto(100);
ERROR_GUARD(MAX_TERM_TYPES);
return Expression::paramTable_->get_value(i);
}

unsigned int
Expression::func_count(void) const
{
Expand Down
6 changes: 1 addition & 5 deletions src/ExpressionVariable.cpp
Expand Up @@ -239,11 +239,7 @@ bool
ExpressionVariable::visit_facts(vector<const Fact*>& inputs, CGContext& cg_context) const
{
int deref_level = get_indirect_level();
const Variable* v = get_var(); //->get_collective();
// JYTODO: integrate this into get_collective?
// if (v->isFieldVarOf_ && v->is_array_field()) {
// v = v->isFieldVarOf_->get_collective();
//}
const Variable* v = get_var();
if (deref_level > 0) {
if (!FactPointTo::is_valid_ptr(v, inputs)) {
return false;
Expand Down
31 changes: 29 additions & 2 deletions src/Fact.cpp
Expand Up @@ -33,15 +33,15 @@
#include "StatementReturn.h"

using namespace std;
std::vector<Fact*> Fact::facts_;

///////////////////////////////////////////////////////////////////////////////

/*
*
*/
Fact::Fact(eFactCategory e) :
eCat(e),
no_more_update(false)
eCat(e)
{
// Nothing else to do.
}
Expand All @@ -54,6 +54,33 @@ Fact::~Fact(void)
// Nothing else to do.
}

/*
* output an assertion about the fact to check the correctness of compiler
* or generation time analysis
*/
void
Fact::OutputAssertion(std::ostream &out, const Statement* s) const
{
if (!is_top()) {
if (s && !is_assertable(s)) {
out << "//";
}
out << "assert (";
Output(out);
out << ");" << endl;
}
}

void
Fact::doFinalization()
{
std::vector<Fact*>::iterator i;
for( i = facts_.begin(); i != facts_.end(); ++i) {
delete (*i);
}
facts_.clear();
}

///////////////////////////////////////////////////////////////////////////////

// Local Variables:
Expand Down
35 changes: 22 additions & 13 deletions src/Fact.h
Expand Up @@ -35,20 +35,19 @@
#include <ostream>
#include <vector>

enum eFactCategory {
eNullPtr=1,
eDeadPtr=2,
ePointTo=4,
//ePointToSize=4,
eIntRange=8,
enum eFactCategory {
ePointTo=1,
eUnionWrite=2,
/* todo
eIntRange=8,
eEquality=16,
eAlias=32,
*/
};

class Statement;
class StatementAssign;
class StatementReturn;
class Block;
class CGContext;
class Variable;
class Expression;
class Lhs;
Expand All @@ -70,27 +69,37 @@ class Fact

virtual int join_visits(const Fact& fact) { return join(fact);}

virtual bool conflict_with(const Fact& /*fact*/) const { return false;};
virtual bool imply(const Fact& /*fact*/) const = 0;

virtual bool is_related(const Fact& fact) const = 0;
// lattice functions
virtual bool is_top(void) const = 0;
virtual bool is_bottom(void) const = 0;
virtual void set_top(void) = 0;
virtual void set_bottom(void) = 0;

virtual bool is_assertable(const Statement* s) const = 0;

virtual bool is_relevant(const Fact& ) const {return false;}
virtual bool is_related(const Fact& fact) const { return eCat == fact.eCat && get_var() == fact.get_var();}

virtual bool equal(const Fact& fact) const { return this == &fact; };

virtual void Output(std::ostream &out) const = 0;

virtual void OutputAssertion(std::ostream &out) const = 0;
virtual void OutputAssertion(std::ostream &out, const Statement* s = NULL) const;

virtual const Variable* get_var(void) const { return 0;};

virtual std::vector<const Fact*> abstract_fact_for_assign(const std::vector<const Fact*>& /*facts*/, const Lhs* /*lhs*/, const Expression* /*rhs*/) = 0;

virtual Fact* abstract_fact_for_return(const std::vector<const Fact*>& /*facts*/, const ExpressionVariable* /*var*/, const Function* /*func*/) {return 0;};

static void doFinalization();

enum eFactCategory eCat;

bool no_more_update;
protected:
// keep track all created facts. used for releasing memory in doFinalization
static std::vector<Fact*> facts_;
};

///////////////////////////////////////////////////////////////////////////////
Expand Down

0 comments on commit 3b31bff

Please sign in to comment.