ExpressionUse use;
use.reference = &expr;
use.ref_scope = current_block;
- use.blocked = access_write;
+ use.blocked = access_write || r_ref_info->blocked;
if(iteration_body && !r_ref_info->trivial)
{
void ExpressionInliner::visit(UnaryExpression &unary)
{
- SetFlag set_write(access_write, access_write || unary.oper->token[1]=='+' || unary.oper->token[1]=='-');
+ SetFlag set_write(access_write, (unary.oper->token[1]=='+' || unary.oper->token[1]=='-'));
visit(unary.expression);
r_trivial = false;
}
r_trivial = true;
visit(assign.right);
- auto i = assignments.find(assign.target);
+ auto i = assignments.find(assign.target.declaration);
if(i!=assignments.end())
{
- if(iteration_body && i->second->expression)
+ if(iteration_body && i->second && i->second->expression)
{
/* Block inlining into previous references within the iteration
statement. On iterations after the first they would refer to the
u.blocked = (k==iteration_body);
}
+ for(; (i!=assignments.end() && i->first.declaration==assign.target.declaration); ++i)
+ if(targets_overlap(i->first, assign.target))
+ i->second->blocked = true;
+
expressions.push_back(ExpressionInfo());
ExpressionInfo &info = expressions.back();
info.target = assign.target;
info.assign_scope = current_block;
info.trivial = r_trivial;
- i->second = &info;
+ assignments[assign.target] = &info;
}
r_trivial = false;
{
bool loop_external = false;
for(AssignmentInfo *a: var_info.assignments)
- {
- bool covered = true;
- for(unsigned j=0; (covered && j<a->target.chain_len && j<target.chain_len); ++j)
- {
- Assignment::Target::ChainType type1 = static_cast<Assignment::Target::ChainType>(a->target.chain[j]&0xC0);
- Assignment::Target::ChainType type2 = static_cast<Assignment::Target::ChainType>(target.chain[j]&0xC0);
- unsigned index1 = a->target.chain[j]&0x3F;
- unsigned index2 = target.chain[j]&0x3F;
- if(type1==Assignment::Target::SWIZZLE || type2==Assignment::Target::SWIZZLE)
- {
- if(type1==Assignment::Target::SWIZZLE && type2==Assignment::Target::SWIZZLE)
- covered = index1&index2;
- else if(type1==Assignment::Target::ARRAY && index1<4)
- covered = index2&(1<<index1);
- else if(type2==Assignment::Target::ARRAY && index2<4)
- covered = index1&(1<<index2);
- /* If it's some other combination (shouldn't happen), leave
- covered as true */
- }
- else
- covered = (type1==type2 && (index1==index2 || index1==0x3F || index2==0x3F));
- }
-
- if(covered)
+ if(targets_overlap(a->target, target))
{
a->used_by.push_back(&node);
if(a->in_loop<in_loop)
loop_external = true;
}
- }
if(loop_external)
loop_ext_refs.push_back(&node);
vector<Node *> saved_refs;
swap(loop_ext_refs, saved_refs);
{
+ if(iter.init_statement)
+ iter.init_statement->visit(*this);
SetForScope<unsigned> set_loop(in_loop, in_loop+1);
- TraversingVisitor::visit(iter);
+ if(iter.condition)
+ iter.condition->visit(*this);
+ iter.body.visit(*this);
+ if(iter.loop_expression)
+ iter.loop_expression->visit(*this);
}
swap(loop_ext_refs, saved_refs);