Skip to content

Commit

Permalink
special handling of unions when doing effect analysis
Browse files Browse the repository at this point in the history
1) recognize the fact that write to one field of an union is in conflict with read/write to another field. This is in contrast with structures.
2) print out statistics of how many union variables are generated at the end of the program
3) clean up statistics collecting a little
  • Loading branch information
Xuejun Yang committed Jun 10, 2011
1 parent e7e4945 commit 4cb9161
Show file tree
Hide file tree
Showing 8 changed files with 77 additions and 34 deletions.
7 changes: 4 additions & 3 deletions src/Bookkeeper.cpp
Expand Up @@ -51,7 +51,7 @@ using namespace std;

// counter for all levels of struct depth
std::vector<int> Bookkeeper::struct_depth_cnts;

int Bookkeeper::union_var_cnt = 0;
std::vector<int> Bookkeeper::expr_depth_cnts;
std::vector<int> Bookkeeper::dereference_level_cnts;
int Bookkeeper::address_taken_cnt = 0;
Expand Down Expand Up @@ -136,7 +136,7 @@ Bookkeeper::output_stmts_statistics(std::ostream &out)
void
Bookkeeper::output_statistics(std::ostream &out)
{
output_struct_statistics(out);
output_struct_union_statistics(out);
out << endl;
output_expr_statistics(out);
out << endl;
Expand All @@ -152,13 +152,14 @@ Bookkeeper::output_statistics(std::ostream &out)
}

void
Bookkeeper::output_struct_statistics(std::ostream &out)
Bookkeeper::output_struct_union_statistics(std::ostream &out)
{
formated_output(out, "max struct depth: ", (struct_depth_cnts.size()-1));
out << "breakdown:" << endl;
for (size_t i=0; i<struct_depth_cnts.size(); i++) {
out << " depth: " << i << ", occurrence: " << struct_depth_cnts[i] << endl;
}
formated_output(out, "total union variables: ", union_var_cnt);
Bookkeeper::output_bitfields(out);
}

Expand Down
6 changes: 4 additions & 2 deletions src/Bookkeeper.h
Expand Up @@ -50,7 +50,7 @@ class Bookkeeper

static void output_statistics(std::ostream &out);

static void output_struct_statistics(std::ostream &out);
static void output_struct_union_statistics(std::ostream &out);

static void output_expr_statistics(std::ostream &out);

Expand Down Expand Up @@ -85,7 +85,9 @@ class Bookkeeper

static void output_var_freshness(std::ostream &out);

static std::vector<int> struct_depth_cnts;
static std::vector<int> struct_depth_cnts;

static int union_var_cnt;

static std::vector<int> expr_depth_cnts;

Expand Down
12 changes: 6 additions & 6 deletions src/CGContext.cpp
Expand Up @@ -207,7 +207,7 @@ CGContext::check_read_var(const Variable *v, const std::vector<const Fact*>& fac
if (is_nonreadable(v)) {
return false;
}
if (effect_context.is_written(v) || effect_context.field_is_written(v)) {
if (effect_context.is_written_partially(v)) {
return false;
}
if (v->is_volatile() && !effect_context.is_side_effect_free()) {
Expand Down Expand Up @@ -329,10 +329,10 @@ CGContext::check_write_var(const Variable *v, const std::vector<const Fact*>& fa
if (is_nonwritable(v) || v->is_const()) {
return false;
}
if (effect_context.is_written(v) || effect_context.field_is_written(v)) {
if (effect_context.is_written_partially(v)) {
return false;
}
if (effect_context.is_read(v) || effect_context.field_is_read(v)) {
if (effect_context.is_read_partially(v)) {
return false;
}
if (v->is_volatile() && !effect_context.is_side_effect_free()) {
Expand Down Expand Up @@ -556,7 +556,7 @@ CGContext::in_conflict(const Effect& eff) const
if (is_nonreadable(v)) {
return true;
}
if (effect_context.is_written(v) || effect_context.field_is_written(v)) {
if (effect_context.is_written_partially(v)) {
return true;
}
// Yang: do we need to consider deref level here?
Expand All @@ -570,10 +570,10 @@ CGContext::in_conflict(const Effect& eff) const
if (is_nonwritable(v) || v->is_const()) {
return true;
}
if (effect_context.is_written(v) || effect_context.field_is_written(v)) {
if (effect_context.is_written_partially(v)) {
return true;
}
if (effect_context.is_read(v) || effect_context.field_is_read(v)) {
if (effect_context.is_read_partially(v)) {
return true;
}
if (v->is_volatile() && !effect_context.is_side_effect_free()) {
Expand Down
44 changes: 44 additions & 0 deletions src/Effect.cpp
Expand Up @@ -434,6 +434,50 @@ Effect::field_is_written(const Variable *v) const
return false;
}

bool
Effect::sibling_field_is_read(const Variable *v) const
{
// check other fields of union/struct
if (v->isFieldVarOf_) {
for (size_t j=0; j<v->isFieldVarOf_->field_vars.size(); j++) {
Variable* field_var = v->isFieldVarOf_->field_vars[j];
if (field_var == v) continue;
if (is_read(field_var) || field_is_read(field_var)) {
return true;
}
}
}
return false;
}

bool
Effect::sibling_field_is_written(const Variable *v) const
{
// check other fields of union/struct
if (v->isFieldVarOf_) {
for (size_t j=0; j<v->isFieldVarOf_->field_vars.size(); j++) {
Variable* field_var = v->isFieldVarOf_->field_vars[j];
if (field_var == v) continue;
if (is_written(field_var) || field_is_written(field_var)) {
return true;
}
}
}
return false;
}

bool
Effect::is_read_partially(const Variable* v) const
{
return is_read(v) || field_is_read(v) || (v->is_union_field() && sibling_field_is_read(v));
}

bool
Effect::is_written_partially(const Variable* v) const
{
return is_written(v) || field_is_written(v) || (v->is_union_field() && sibling_field_is_written(v));
}

/*
* consolidate the read/write set
*/
Expand Down
4 changes: 4 additions & 0 deletions src/Effect.h
Expand Up @@ -65,6 +65,10 @@ class Effect
bool is_written(std::string vname) const;
bool field_is_read(const Variable *v) const;
bool field_is_written(const Variable *v) const;
bool sibling_field_is_read(const Variable *v) const;
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 has_race_with(const Effect &e) const;
bool is_empty(void) const;
void consolidate(void);
Expand Down
4 changes: 0 additions & 4 deletions src/Probabilities.cpp
Expand Up @@ -654,10 +654,6 @@ Probabilities::set_default_simple_types_prob()
else {
SET_SINGLE_NAME("long_long_prob", LongLong, 0);
SET_SINGLE_NAME("ulong_long_prob", ULongLong, 0);
if (CGOptions::x86_64()) {
SET_SINGLE_NAME("long_prob", Long, 0);
SET_SINGLE_NAME("ulong_prob", ULong, 0);
}
}

set_group_prob(true, pSimpleTypesProb, m);
Expand Down
1 change: 1 addition & 0 deletions src/Variable.h
Expand Up @@ -87,6 +87,7 @@ class Variable
bool is_volatile_after_deref(int deref_level) const;
bool has_field_var(const Variable* v) const;
bool is_field_var(void) const { return isFieldVarOf_ != 0; };
bool is_union_field(void) const { return isFieldVarOf_ != 0 && isFieldVarOf_->type->eType == eUnion; };
bool is_array_field(void) const;
bool is_virtual(void) const;
bool is_aggregate(void) const { return type && type->is_aggregate(); }
Expand Down
33 changes: 14 additions & 19 deletions src/VariableSelector.cpp
Expand Up @@ -225,10 +225,6 @@ VariableSelector::has_dereferenceable_var(const vector<Variable *>& vars, const
bool
VariableSelector::is_eligible_var(const Variable* var, int deref_level, Effect::Access access, const CGContext& cg_context)
{
// JYTODO: integrate this into get_collective?
//if (var->isFieldVarOf_ && var->is_array_field()) {
// var = var->isFieldVarOf_->get_collective();
//}
const Variable* coll = var->get_collective();
if (coll != var) {
CGContext cg_tmp(cg_context);
Expand Down Expand Up @@ -256,15 +252,15 @@ VariableSelector::is_eligible_var(const Variable* var, int deref_level, Effect::
// We can neither read nor write a variable that is being written in
// the current effect context.
if (((access == Effect::READ) || (access == Effect::WRITE))
&& (effect_context.is_written(var) || effect_context.field_is_written(var))) {
&& (effect_context.is_written_partially(var))) {
return false;
}
// ISSUE: generating "strictly conforming" programs.
//
// We cannot write a variable that is being read in the current effect context.
// JYTODO: this is too restrictive, with dereference, var is not the variable
// being written, but the pointed variable. Nevertheless, we excluded var here
if ((access == Effect::WRITE && deref_level==0) && (effect_context.is_read(var) || effect_context.field_is_read(var))) {
if ((access == Effect::WRITE && deref_level==0) && effect_context.is_read_partially(var)) {
return false;
}
// ISSUE: generating correct C programs.
Expand Down Expand Up @@ -532,8 +528,6 @@ VariableSelector::GenerateNewGlobal(Effect::Access access, const CGContext &cg_c
tmp_count++;
Variable* var = create_and_initialize(access, cg_context, t, &var_qfer, 0, name);

Bookkeeper::record_vars_with_bitfields(t);
incr_counter(Bookkeeper::struct_depth_cnts, t->get_struct_depth());
GlobalList.push_back(var);
// for DFA
FactMgr* fm = get_fact_mgr(&cg_context);
Expand Down Expand Up @@ -562,8 +556,6 @@ VariableSelector::GenerateNewNonArrayGlobal(Effect::Access access, const CGConte
ERROR_GUARD(NULL);
Variable *var = new_variable(name, t, init, qfer);

Bookkeeper::record_vars_with_bitfields(t);
incr_counter(Bookkeeper::struct_depth_cnts, t->get_struct_depth());
GlobalList.push_back(var);
// for DFA
FactMgr* fm = get_fact_mgr(&cg_context);
Expand Down Expand Up @@ -927,9 +919,6 @@ VariableSelector::GenerateNewParentLocal(Block &block,
string name = RandomLocalName();

Variable* var = create_and_initialize(access, cg_context, t, &var_qfer, blk, name);

Bookkeeper::record_vars_with_bitfields(t);
incr_counter(Bookkeeper::struct_depth_cnts, t->get_struct_depth());
blk->local_vars.push_back(var);
FactMgr* fm = get_fact_mgr(&cg_context);
fm->add_new_local_var_fact(blk, var->get_collective());
Expand Down Expand Up @@ -1206,10 +1195,17 @@ VariableSelector::select(Effect::Access access,
if (var && !cg_context.get_effect_context().is_side_effect_free()) {
assert(!var->is_volatile());
}
if (var_created) {
Bookkeeper::use_new_var_cnt++;
} else {
Bookkeeper::use_old_var_cnt++;
// record statistics
if (var) {
if (var_created) {
const Type* t = var->type;
Bookkeeper::use_new_var_cnt++;
Bookkeeper::record_vars_with_bitfields(t);
incr_counter(Bookkeeper::struct_depth_cnts, t->get_struct_depth());
if (t->eType == eUnion) Bookkeeper::union_var_cnt++;
} else {
Bookkeeper::use_old_var_cnt++;
}
}
return var;
}
Expand Down Expand Up @@ -1355,8 +1351,7 @@ VariableSelector::select_array(const CGContext &cg_context)
ArrayVariable* av = dynamic_cast<ArrayVariable*>(vars[i]);
assert(av);
if (av->collective == 0) {
if (!cg_context.get_effect_context().is_read(av) &&
!cg_context.get_effect_context().field_is_read(av) &&
if (!cg_context.get_effect_context().is_read_partially(av) &&
!cg_context.get_effect_context().is_written(av) &&
(cg_context.get_effect_context().is_side_effect_free() || !av->is_volatile()) &&
!av->is_const() &&
Expand Down

0 comments on commit 4cb9161

Please sign in to comment.