X-Git-Url: http://git.tdb.fi/?p=libs%2Fgl.git;a=blobdiff_plain;f=source%2Fglsl%2Foptimize.cpp;h=ed20bb175dcc9277e1ff84e2e1a1734b2279668f;hp=044dd4e5a29ef1eefde6985b5c4798b93cf239fd;hb=8bf70f4d445cf63386ad7aafc5b3ebdbd8369939;hpb=29fb23fb9c6eb32b1157a09cf79754a630702f9e diff --git a/source/glsl/optimize.cpp b/source/glsl/optimize.cpp index 044dd4e5..ed20bb17 100644 --- a/source/glsl/optimize.cpp +++ b/source/glsl/optimize.cpp @@ -592,6 +592,31 @@ T ConstantFolder::evaluate_arithmetic(char oper, T left, T right) } } +template +T ConstantFolder::evaluate_int_special_op(char oper, T left, T right) +{ + switch(oper) + { + case '%': return left%right; + case '<': return left<': return left>>right; + default: return T(); + } +} + +template +void ConstantFolder::convert_to_result(const Variant &value) +{ + if(value.check_type()) + set_result(static_cast(value.value())); + else if(value.check_type()) + set_result(static_cast(value.value())); + else if(value.check_type()) + set_result(static_cast(value.value())); + else if(value.check_type()) + set_result(static_cast(value.value())); +} + void ConstantFolder::set_result(const Variant &value, bool literal) { r_constant_value = value; @@ -617,6 +642,8 @@ void ConstantFolder::visit(RefPtr &expr) literal->token = (r_constant_value.value() ? "true" : "false"); else if(r_constant_value.check_type()) literal->token = lexical_cast(r_constant_value.value()); + else if(r_constant_value.check_type()) + literal->token = lexical_cast(r_constant_value.value())+"u"; else if(r_constant_value.check_type()) { literal->token = lexical_cast(r_constant_value.value()); @@ -630,6 +657,7 @@ void ConstantFolder::visit(RefPtr &expr) } literal->value = r_constant_value; expr = literal; + r_any_folded = true; } void ConstantFolder::visit(Literal &literal) @@ -721,11 +749,15 @@ void ConstantFolder::visit(BinaryExpression &binary) set_result(evaluate_logical(oper, left_value.value(), r_constant_value.value())); else if(!oper2 && left_value.check_type()) set_result(evaluate_logical(oper, left_value.value(), r_constant_value.value())); + else if(!oper2 && left_value.check_type()) + set_result(evaluate_logical(oper, left_value.value(), r_constant_value.value())); } else if((oper=='<' || oper=='>') && oper2!=oper) { if(left_value.check_type()) set_result(evaluate_relation(binary.oper->token, left_value.value(), r_constant_value.value())); + else if(left_value.check_type()) + set_result(evaluate_relation(binary.oper->token, left_value.value(), r_constant_value.value())); else if(left_value.check_type()) set_result(evaluate_relation(binary.oper->token, left_value.value(), r_constant_value.value())); } @@ -733,27 +765,26 @@ void ConstantFolder::visit(BinaryExpression &binary) { if(left_value.check_type()) set_result((left_value.value()==r_constant_value.value()) == (oper=='=')); - if(left_value.check_type()) + else if(left_value.check_type()) + set_result((left_value.value()==r_constant_value.value()) == (oper=='=')); + else if(left_value.check_type()) set_result((left_value.value()==r_constant_value.value()) == (oper=='=')); } else if(oper=='+' || oper=='-' || oper=='*' || oper=='/') { if(left_value.check_type()) set_result(evaluate_arithmetic(oper, left_value.value(), r_constant_value.value())); + else if(left_value.check_type()) + set_result(evaluate_arithmetic(oper, left_value.value(), r_constant_value.value())); else if(left_value.check_type()) set_result(evaluate_arithmetic(oper, left_value.value(), r_constant_value.value())); } else if(oper=='%' || ((oper=='<' || oper=='>') && oper2==oper)) { - if(!left_value.check_type()) - return; - - if(oper=='%') - set_result(left_value.value()%r_constant_value.value()); - else if(oper=='<') - set_result(left_value.value()<()); - else if(oper=='>') - set_result(left_value.value()>>r_constant_value.value()); + if(left_value.check_type()) + set_result(evaluate_int_special_op(oper, left_value.value(), r_constant_value.value())); + else if(left_value.check_type()) + set_result(evaluate_int_special_op(oper, left_value.value(), r_constant_value.value())); } } @@ -771,6 +802,30 @@ void ConstantFolder::visit(TernaryExpression &ternary) void ConstantFolder::visit(FunctionCall &call) { + if(call.constructor && call.type && call.arguments.size()==1) + { + const BasicTypeDeclaration *basic = dynamic_cast(call.type); + if(basic) + { + call.arguments[0]->visit(*this); + bool can_fold = r_constant; + r_constant = false; + if(!can_fold) + return; + + if(basic->kind==BasicTypeDeclaration::BOOL) + convert_to_result(r_constant_value); + else if(basic->kind==BasicTypeDeclaration::INT && basic->size==32 && basic->sign) + convert_to_result(r_constant_value); + else if(basic->kind==BasicTypeDeclaration::INT && basic->size==32 && !basic->sign) + convert_to_result(r_constant_value); + else if(basic->kind==BasicTypeDeclaration::FLOAT && basic->size==32) + convert_to_result(r_constant_value); + + return; + } + } + TraversingVisitor::visit(call); r_constant = false; } @@ -1002,7 +1057,8 @@ UnusedVariableRemover::UnusedVariableRemover(): assignment_target(false), r_side_effects(false), in_struct(false), - composite_reference(false) + composite_reference(false), + in_loop(0) { } bool UnusedVariableRemover::apply(Stage &s) @@ -1046,6 +1102,7 @@ void UnusedVariableRemover::referenced(const Assignment::Target &target, Node &n var_info.referenced = true; if(!assignment_target) { + bool loop_external = false; for(vector::const_iterator i=var_info.assignments.begin(); i!=var_info.assignments.end(); ++i) { bool covered = true; @@ -1069,9 +1126,17 @@ void UnusedVariableRemover::referenced(const Assignment::Target &target, Node &n else covered = ((*i)->target.chain[j]==target.chain[j]); } + if(covered) + { (*i)->used_by.push_back(&node); + if((*i)->in_loop saved_refs; + swap(loop_ext_refs, saved_refs); + { + SetForScope 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::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