Skip to content

Commit

Permalink
supporting side-effecting expressions and bug fixing for unions
Browse files Browse the repository at this point in the history
1) add two more expression types: ExpressionAssign for embedded assignments; and ExpressionComma for comma expressions. Give them enough probability to show up in random programs (10% each for now)

2) allow pointer fields inside unions

3) expanded VectorFilter so it filter out candidates after looking up a ProbabilityTable. This is useful for choosing Expression/statement types where a random number is translated into a type based on pre-determined distributions.

4) expand the points-to analysis to accommodate the facts that a shallow copy of struct/unions could impact multiple pointers that are fields of copied structs.

5) expand the effect analysis to accommodate the facts that RHS of assignments could have side effect if it contains 1) function call, 2) embedded assignments, or 3) comma expressions.

6) to simplify points-to analysis, disallow an integer union field to be loop control variable if another field of the same union happens to be pointer

7) rename class "Table" to "TableEntry"

8) fix some bugs in analyzing read/write conflicts between union fields

9) add debugging code to the random number generator

10) kill some warnings barked by MSVC and gcc

11) clean up obsolete code
  • Loading branch information
Xuejun Yang committed Jul 11, 2011
1 parent da55019 commit 1eb4fd9
Show file tree
Hide file tree
Showing 41 changed files with 530 additions and 523 deletions.
6 changes: 3 additions & 3 deletions src/CGContext.cpp
Expand Up @@ -202,13 +202,13 @@ 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)) {
if (!read_indices(v, facts)) {
return false;
}
if (!read_indices(v, facts)) {
v = v->get_collective();
if (FactUnion::is_nonreadable_field(v, facts)) {
return false;
}
v = v->get_collective();
if (is_nonreadable(v)) {
return false;
}
Expand Down
11 changes: 11 additions & 0 deletions src/Constant.cpp
Expand Up @@ -433,6 +433,17 @@ Constant::equals(int num) const
return StringUtils::str2int(value) == num;
}

string
Constant::get_field(size_t fid) const
{
vector<string> fields;
StringUtils::split_string(value, fields, "{},");
if (fid < fields.size()) {
return fields[fid];
}
return "";
}

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

/*
Expand Down
2 changes: 2 additions & 0 deletions src/Constant.h
Expand Up @@ -73,6 +73,8 @@ class Constant : public Expression
// Unused:
const std::string &get_value(void) const { return value; }

string get_field(size_t fid) const;

virtual bool less_than(int num) const;
virtual bool not_equals(int num) const;
virtual bool equals(int num) const;
Expand Down
9 changes: 9 additions & 0 deletions src/DefaultRndNumGenerator.cpp
Expand Up @@ -33,6 +33,7 @@
#include <cstdlib>
#include <iostream>
#include <sstream>
#include <fstream>

#include "Filter.h"
#include "SequenceFactory.h"
Expand Down Expand Up @@ -116,9 +117,15 @@ DefaultRndNumGenerator::add_number(int v, int bound, int k)
unsigned int
DefaultRndNumGenerator::rnd_upto(const unsigned int n, const Filter *f, const std::string *where)
{
static int g = 0;
int h = g;
if (h == 440)
BREAK_NOP; // for debugging
unsigned int v = genrand() % n;
unsigned INT64 local_depth = rand_depth_;
rand_depth_++;
//ofstream out("rnd.log", ios_base::app);
//out << g++ << ": " << v << "(" << n << ")" << endl;

if (f) {
while (f->filter(v)) {
Expand All @@ -127,8 +134,10 @@ DefaultRndNumGenerator::rnd_upto(const unsigned int n, const Filter *f, const st
// This will also overwrite the value added in the map.
rand_depth_ = local_depth+1;
v = genrand() % n;
/*out << g++ << ": " << v << "(" << n << ")" << endl;*/
}
}
//out.close();
if (where) {
std::ostringstream ss;
ss << *where << "->";
Expand Down
46 changes: 24 additions & 22 deletions src/Effect.cpp
Expand Up @@ -440,37 +440,39 @@ Effect::field_is_written(const Variable *v) const
bool
Effect::sibling_union_field_is_read(const Variable *v) const
{
while (v->field_var_of) {
// check other fields of the union
if (v->field_var_of->type->eType == eUnion) {
for (size_t j=0; j<v->field_var_of->field_vars.size(); j++) {
Variable* field_var = v->field_var_of->field_vars[j];
if (field_var == v) continue;
if (is_read(field_var) || field_is_read(field_var)) {
return true;
}
const Variable* you = v->get_collective();
// find the union variable(s) that contains you
for (; you && you->type->eType != eUnion; you = you->field_var_of)
;
if (you) {
for (size_t i=0; i<read_vars.size(); i++) {
const Variable* me = read_vars[i]->get_collective();
for (; me && me->type->eType != eUnion; me = me->field_var_of)
;
if (you == me) {
return true;
}
}
v = v->field_var_of;
}
return false;
}

bool
Effect::sibling_union_field_is_written(const Variable *v) const
{
while (v->field_var_of) {
// check other fields of the union
if (v->field_var_of->type->eType == eUnion) {
for (size_t j=0; j<v->field_var_of->field_vars.size(); j++) {
Variable* field_var = v->field_var_of->field_vars[j];
if (field_var == v) continue;
if (is_written(field_var) || field_is_written(field_var)) {
return true;
}
{
const Variable* you = v->get_collective();
// find the union variable(s) that contains you
for (; you && you->type->eType != eUnion; you = you->field_var_of)
;
if (you) {
for (size_t i=0; i<write_vars.size(); i++) {
const Variable* me = write_vars[i]->get_collective();
for (; me && me->type->eType != eUnion; me = me->field_var_of)
;
if (you == me) {
return true;
}
}
v = v->field_var_of;
}
return false;
}
Expand Down Expand Up @@ -621,7 +623,7 @@ 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()) {
if (read_vars[i]->is_inside_union_field()) {
return true;
}
}
Expand Down

0 comments on commit 1eb4fd9

Please sign in to comment.