Skip to content

Commit

Permalink
bug fix for union: consider callees when determining if a function re…
Browse files Browse the repository at this point in the history
…ads union field
  • Loading branch information
Xuejun Yang committed Jun 17, 2011
1 parent 1f772fa commit 9bdeb8d
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 34 deletions.
24 changes: 16 additions & 8 deletions src/Function.cpp
Expand Up @@ -601,21 +601,29 @@ Function::generate_body_with_known_params(const CGContext &prev_context, Effect&
ERROR_RETURN();
body->set_depth_protect(true);

compute_summary();

make_return_const();
ERROR_RETURN();

// Mark this function as built.
build_state = BUILT;
}

void
Function::compute_summary(void)
{
FactMgr* fm = get_fact_mgr_for_func(this);
// compute the pointers that are statically referenced in the function
// including ones referenced by its callees
body->get_referenced_ptrs(referenced_ptrs);

// Compute the function's externally visible effect. Currently, this
// is just the effect on globals.
// Compute the function's externally visible effect.
//effect.add_external_effect(*cg_context.get_effect_accum());
feffect.add_external_effect(fm->map_stm_effect[body]);
union_field_read = fm->map_stm_effect[body].union_field_is_read();

make_return_const();
ERROR_RETURN();

// Mark this function as built.
build_state = BUILT;
// determine whether an union field is read
union_field_read = body->read_union_field();
}

/*
Expand Down
1 change: 1 addition & 0 deletions src/Function.h
Expand Up @@ -78,6 +78,7 @@ class Function
static void doFinalization();

void generate_body_with_known_params(const CGContext &prev_context, Effect& effect_accum);
void compute_summary(void);

void Output(std::ostream &);
void OutputForwardDecl(std::ostream &);
Expand Down
56 changes: 30 additions & 26 deletions src/Statement.cpp
Expand Up @@ -51,6 +51,7 @@
#include "Expression.h"
#include "ExpressionFuncall.h"
#include "FunctionInvocation.h"
#include "FunctionInvocationUser.h"
#include "FactPointTo.h"

#include "Block.h" // temporary; don't want to depend on subclases!
Expand Down Expand Up @@ -672,6 +673,24 @@ Statement::is_jump_target_from_other_blocks(void) const
return false;
}

bool
Statement::read_union_field(void) const
{
FactMgr* fm = get_fact_mgr_for_func(func);
assert(fm);
if (fm->map_stm_effect[this].union_field_is_read()) {
return true;
}
vector<const FunctionInvocationUser*> calls;
get_called_funcs(calls);
for (size_t i=0; i<calls.size(); i++) {
if (calls[i]->get_func()->union_field_read) {
return true;
}
}
return false;
}

/*
* return true if s is contained inside this statement
*/
Expand Down Expand Up @@ -750,33 +769,18 @@ Statement::get_direct_invocation(void) const
void
Statement::get_called_funcs(std::vector<const FunctionInvocationUser*>& funcs) const
{
if (eType == eAssign) {
((const StatementAssign*)this)->get_rhs()->get_called_funcs(funcs);
}
else if (eType == eInvoke) {
((const StatementExpr*)this)->get_invoke()->get_called_funcs(funcs);
}
else if (eType == eBlock) {
const Block* b = (const Block*)this;
size_t i;
for (i=0; i<b->stms.size(); i++) {
b->stms[i]->get_called_funcs(funcs);
}
size_t i;
vector<const Expression*> exprs;
vector<const Block*> blks;
get_exprs(exprs);
get_blocks(blks);
for (i=0; i<exprs.size(); i++) {
exprs[i]->get_called_funcs(funcs);
}
else if (eType == eIfElse) {
const StatementIf* si = (const StatementIf*)this;
si->get_test()->get_called_funcs(funcs);
si->get_true_branch()->get_called_funcs(funcs);
si->get_false_branch()->get_called_funcs(funcs);
}
else if (eType == eFor) {
const StatementFor* sf = (const StatementFor*)this;
sf->get_body()->get_called_funcs(funcs);
}
else if (eType == eArrayOp) {
const StatementArrayOp* sa = (const StatementArrayOp*)this;
if (sa->body) {
sa->body->get_called_funcs(funcs);
for (i=0; i<blks.size(); i++) {
for (size_t j=0; j<blks[i]->stms.size(); j++) {
const Statement* s = blks[i]->stms[j];
s->get_called_funcs(funcs);
}
}
}
Expand Down
2 changes: 2 additions & 0 deletions src/Statement.h
Expand Up @@ -145,6 +145,8 @@ class Statement

bool is_jump_target_from_other_blocks(void) const;

bool read_union_field(void) const;

virtual void get_blocks(std::vector<const Block*>& /* blks */) const = 0;
virtual void get_exprs(std::vector<const Expression*>& /* exps */) const = 0;

Expand Down

0 comments on commit 9bdeb8d

Please sign in to comment.