]> git.tdb.fi Git - libs/gl.git/blobdiff - source/glsl/optimize.cpp
Rearrange expression node replacement
[libs/gl.git] / source / glsl / optimize.cpp
index a999a654db84ac8ac072ef7fb817d5107643a584..f938314814ea9cd4211279d5e94ff817c2a92fcc 100644 (file)
@@ -202,6 +202,7 @@ void FunctionInliner::visit_and_inline(RefPtr<Expression> &ptr)
                ptr = r_inline_result;
                r_any_inlined = true;
        }
+       r_inline_result = 0;
 }
 
 void FunctionInliner::visit(Block &block)
@@ -218,20 +219,17 @@ void FunctionInliner::visit(Block &block)
 void FunctionInliner::visit(UnaryExpression &unary)
 {
        visit_and_inline(unary.expression);
-       r_inline_result = 0;
 }
 
 void FunctionInliner::visit(BinaryExpression &binary)
 {
        visit_and_inline(binary.left);
        visit_and_inline(binary.right);
-       r_inline_result = 0;
 }
 
 void FunctionInliner::visit(MemberAccess &memacc)
 {
        visit_and_inline(memacc.left);
-       r_inline_result = 0;
 }
 
 void FunctionInliner::visit(FunctionCall &call)
@@ -259,8 +257,6 @@ void FunctionInliner::visit(FunctionCall &call)
                inlined further. */
                inlineable.erase(current_function);
        }
-       else
-               r_inline_result = 0;
 }
 
 void FunctionInliner::visit(ExpressionStatement &expr)
@@ -272,7 +268,6 @@ void FunctionInliner::visit(VariableDeclaration &var)
 {
        if(var.init_expression)
                visit_and_inline(var.init_expression);
-       r_inline_result = 0;
 }
 
 void FunctionInliner::visit(FunctionDeclaration &func)
@@ -289,11 +284,15 @@ void FunctionInliner::visit(Conditional &cond)
 
 void FunctionInliner::visit(Iteration &iter)
 {
-       SetForScope<Block *> set_block(current_block, &iter.body);
+       /* Visit the initialization statement before entering the loop body so the
+       inlined statements get inserted outside. */
        if(iter.init_statement)
                iter.init_statement->visit(*this);
-       /* Skip the condition and loop expression parts because they're executed on
-       every iteration of the loop */
+
+       SetForScope<Block *> set_block(current_block, &iter.body);
+       /* Skip the condition and loop expression parts because they're not properly
+       inside the body block.  Inlining anything into them will require a more
+       comprehensive transformation. */
        iter.body.visit(*this);
 }
 
@@ -360,6 +359,7 @@ void ExpressionInliner::visit_and_record(RefPtr<Expression> &ptr, const Operator
                        r_ref_info->inline_on_rhs = on_rhs;
                }
        }
+       r_ref_info = 0;
 }
 
 void ExpressionInliner::inline_expression(Expression &expr, RefPtr<Expression> &ptr, const Operator *outer_oper, const Operator *inner_oper, bool on_rhs)
@@ -435,7 +435,6 @@ void ExpressionInliner::visit(VariableReference &var)
 void ExpressionInliner::visit(MemberAccess &memacc)
 {
        visit_and_record(memacc.left, memacc.oper, false);
-       r_ref_info = 0;
        r_oper = memacc.oper;
        r_trivial = false;
 }
@@ -444,7 +443,6 @@ void ExpressionInliner::visit(UnaryExpression &unary)
 {
        SetFlag set_target(mutating, mutating || unary.oper->token[1]=='+' || unary.oper->token[1]=='-');
        visit_and_record(unary.expression, unary.oper, false);
-       r_ref_info = 0;
        r_oper = unary.oper;
        r_trivial = false;
 }
@@ -456,7 +454,6 @@ void ExpressionInliner::visit(BinaryExpression &binary)
                SetFlag clear_target(mutating, false);
                visit_and_record(binary.right, binary.oper, true);
        }
-       r_ref_info = 0;
        r_oper = binary.oper;
        r_trivial = false;
 }
@@ -485,7 +482,6 @@ void ExpressionInliner::visit(Assignment &assign)
                }
        }
 
-       r_ref_info = 0;
        r_oper = assign.oper;
        r_trivial = false;
 }
@@ -494,7 +490,6 @@ void ExpressionInliner::visit(FunctionCall &call)
 {
        for(NodeArray<Expression>::iterator i=call.arguments.begin(); i!=call.arguments.end(); ++i)
                visit_and_record(*i, 0, false);
-       r_ref_info = 0;
        r_oper = 0;
        r_trivial = false;
 }
@@ -618,6 +613,68 @@ UnusedVariableRemover::VariableInfo::VariableInfo():
 { }
 
 
+bool UnusedTypeRemover::apply(Stage &stage)
+{
+       stage.content.visit(*this);
+       NodeRemover().apply(stage, unused_nodes);
+       return !unused_nodes.empty();
+}
+
+void UnusedTypeRemover::visit(Literal &literal)
+{
+       unused_nodes.erase(literal.type);
+}
+
+void UnusedTypeRemover::visit(UnaryExpression &unary)
+{
+       unused_nodes.erase(unary.type);
+       TraversingVisitor::visit(unary);
+}
+
+void UnusedTypeRemover::visit(BinaryExpression &binary)
+{
+       unused_nodes.erase(binary.type);
+       TraversingVisitor::visit(binary);
+}
+
+void UnusedTypeRemover::visit(FunctionCall &call)
+{
+       unused_nodes.erase(call.type);
+       TraversingVisitor::visit(call);
+}
+
+void UnusedTypeRemover::visit(BasicTypeDeclaration &type)
+{
+       if(type.base_type)
+               unused_nodes.erase(type.base_type);
+       unused_nodes.insert(&type);
+}
+
+void UnusedTypeRemover::visit(ImageTypeDeclaration &type)
+{
+       if(type.base_type)
+               unused_nodes.erase(type.base_type);
+       unused_nodes.insert(&type);
+}
+
+void UnusedTypeRemover::visit(StructDeclaration &strct)
+{
+       unused_nodes.insert(&strct);
+       TraversingVisitor::visit(strct);
+}
+
+void UnusedTypeRemover::visit(VariableDeclaration &var)
+{
+       unused_nodes.erase(var.type_declaration);
+}
+
+void UnusedTypeRemover::visit(FunctionDeclaration &func)
+{
+       unused_nodes.erase(func.return_type_declaration);
+       TraversingVisitor::visit(func);
+}
+
+
 UnusedVariableRemover::UnusedVariableRemover():
        aggregate(0),
        r_assignment(0),
@@ -674,7 +731,8 @@ void UnusedVariableRemover::visit(InterfaceBlockReference &iface)
 
 void UnusedVariableRemover::visit(MemberAccess &memacc)
 {
-       r_assign_to_subfield = true;
+       if(assignment_target)
+               r_assign_to_subfield = true;
        TraversingVisitor::visit(memacc);
        unused_nodes.erase(memacc.declaration);
 }
@@ -755,7 +813,6 @@ void UnusedVariableRemover::visit(ExpressionStatement &expr)
 void UnusedVariableRemover::visit(StructDeclaration &strct)
 {
        SetForScope<Node *> set(aggregate, &strct);
-       unused_nodes.insert(&strct);
        TraversingVisitor::visit(strct);
 }
 
@@ -769,7 +826,6 @@ void UnusedVariableRemover::visit(VariableDeclaration &var)
                if(var.init_expression)
                        record_assignment(var, *var.init_expression, false);
        }
-       unused_nodes.erase(var.type_declaration);
        TraversingVisitor::visit(var);
 }