assignment_target(false),
r_side_effects(false),
in_struct(false),
- composite_reference(false)
+ composite_reference(false),
+ in_loop(0)
{ }
bool UnusedVariableRemover::apply(Stage &s)
var_info.referenced = true;
if(!assignment_target)
{
+ bool loop_external = false;
for(vector<AssignmentInfo *>::const_iterator i=var_info.assignments.begin(); i!=var_info.assignments.end(); ++i)
{
bool covered = true;
else
covered = ((*i)->target.chain[j]==target.chain[j]);
}
+
if(covered)
+ {
(*i)->used_by.push_back(&node);
+ if((*i)->in_loop<in_loop)
+ loop_external = true;
+ }
}
+
+ if(loop_external)
+ loop_ext_refs.push_back(&node);
}
}
AssignmentInfo &assign_info = assignments.back();
assign_info.node = &node;
assign_info.target = target;
+ assign_info.in_loop = in_loop;
/* An assignment to the target hides any assignments to the same target or
its subfields. */
void UnusedVariableRemover::visit(Iteration &iter)
{
BlockVariableMap saved_vars = variables;
- TraversingVisitor::visit(iter);
+ vector<Node *> saved_refs;
+ swap(loop_ext_refs, saved_refs);
+ {
+ SetForScope<unsigned> set_loop(in_loop, in_loop+1);
+ TraversingVisitor::visit(iter);
+ }
+ swap(loop_ext_refs, saved_refs);
+
+ /* Visit the external references of the loop again to record assignments
+ done in the loop as used. */
+ for(vector<Node *>::const_iterator i=saved_refs.begin(); i!=saved_refs.end(); ++i)
+ (*i)->visit(*this);
/* Merge assignments from the iteration, without clearing previous state.
Further analysis is needed to determine which parts of the iteration body