X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fglsl%2Foptimize.cpp;h=d21512f6c82e4e6bdef3ccbdf38f70cd6e018e66;hb=4737d137d0a1c7fed868c4adc7a3d7e00ba7681c;hp=68d3f1d77a9b1233701629b2f27b319bfec43e3d;hpb=3a6eb030fb4eca4c2a317f270704fddf31613130;p=libs%2Fgl.git diff --git a/source/glsl/optimize.cpp b/source/glsl/optimize.cpp index 68d3f1d7..d21512f6 100644 --- a/source/glsl/optimize.cpp +++ b/source/glsl/optimize.cpp @@ -1,5 +1,6 @@ #include #include +#include #include "optimize.h" #include "reflect.h" @@ -553,18 +554,6 @@ void ExpressionInliner::visit(Iteration &iter) } -BasicTypeDeclaration::Kind ConstantFolder::get_value_kind(const Variant &value) -{ - if(value.check_type()) - return BasicTypeDeclaration::BOOL; - else if(value.check_type()) - return BasicTypeDeclaration::INT; - else if(value.check_type()) - return BasicTypeDeclaration::FLOAT; - else - return BasicTypeDeclaration::VOID; -} - template T ConstantFolder::evaluate_logical(char oper, T left, T right) { @@ -603,6 +592,29 @@ 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())); +} + void ConstantFolder::set_result(const Variant &value, bool literal) { r_constant_value = value; @@ -623,20 +635,22 @@ void ConstantFolder::visit(RefPtr &expr) if(!r_constant || r_literal || r_uses_iter_var) return; - BasicTypeDeclaration::Kind kind = get_value_kind(r_constant_value); - if(kind==BasicTypeDeclaration::VOID) - { - r_constant = false; - return; - } - RefPtr literal = new Literal; - if(kind==BasicTypeDeclaration::BOOL) + if(r_constant_value.check_type()) literal->token = (r_constant_value.value() ? "true" : "false"); - else if(kind==BasicTypeDeclaration::INT) + else if(r_constant_value.check_type()) literal->token = lexical_cast(r_constant_value.value()); - else if(kind==BasicTypeDeclaration::FLOAT) + else if(r_constant_value.check_type()) + { literal->token = lexical_cast(r_constant_value.value()); + if(isnumrc(literal->token)) + literal->token += ".0"; + } + else + { + r_constant = false; + return; + } literal->value = r_constant_value; expr = literal; } @@ -678,25 +692,27 @@ void ConstantFolder::visit(UnaryExpression &unary) if(!can_fold) return; - BasicTypeDeclaration::Kind kind = get_value_kind(r_constant_value); - char oper = unary.oper->token[0]; char oper2 = unary.oper->token[1]; if(oper=='!') { - if(kind==BasicTypeDeclaration::BOOL) + if(r_constant_value.check_type()) set_result(!r_constant_value.value()); } else if(oper=='~') { - if(kind==BasicTypeDeclaration::INT) + if(r_constant_value.check_type()) set_result(~r_constant_value.value()); + else if(r_constant_value.check_type()) + set_result(~r_constant_value.value()); } else if(oper=='-' && !oper2) { - if(kind==BasicTypeDeclaration::INT) + if(r_constant_value.check_type()) set_result(-r_constant_value.value()); - else if(kind==BasicTypeDeclaration::FLOAT) + else if(r_constant_value.check_type()) + set_result(-r_constant_value.value()); + else if(r_constant_value.check_type()) set_result(-r_constant_value.value()); } } @@ -716,53 +732,44 @@ void ConstantFolder::visit(BinaryExpression &binary) if(!can_fold) return; - BasicTypeDeclaration::Kind left_kind = get_value_kind(left_value); - BasicTypeDeclaration::Kind right_kind = get_value_kind(r_constant_value); // Currently only expressions with both sides of equal types are handled. - if(left_kind!=right_kind) + if(!left_value.check_same_type(r_constant_value)) return; char oper = binary.oper->token[0]; char oper2 = binary.oper->token[1]; if(oper=='&' || oper=='|' || oper=='^') { - if(oper2==oper && left_kind==BasicTypeDeclaration::BOOL) + if(oper2==oper && left_value.check_type()) set_result(evaluate_logical(oper, left_value.value(), r_constant_value.value())); - else if(!oper2 && left_kind==BasicTypeDeclaration::INT) + 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_kind==BasicTypeDeclaration::INT) + if(left_value.check_type()) set_result(evaluate_relation(binary.oper->token, left_value.value(), r_constant_value.value())); - else if(left_kind==BasicTypeDeclaration::FLOAT) + else if(left_value.check_type()) set_result(evaluate_relation(binary.oper->token, left_value.value(), r_constant_value.value())); } else if((oper=='=' || oper=='!') && oper2=='=') { - if(left_kind==BasicTypeDeclaration::INT) + if(left_value.check_type()) set_result((left_value.value()==r_constant_value.value()) == (oper=='=')); - if(left_kind==BasicTypeDeclaration::FLOAT) + if(left_value.check_type()) set_result((left_value.value()==r_constant_value.value()) == (oper=='=')); } else if(oper=='+' || oper=='-' || oper=='*' || oper=='/') { - if(left_kind==BasicTypeDeclaration::INT) + if(left_value.check_type()) set_result(evaluate_arithmetic(oper, left_value.value(), r_constant_value.value())); - else if(left_kind==BasicTypeDeclaration::FLOAT) + 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_kind!=BasicTypeDeclaration::INT) - 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())); } } @@ -780,6 +787,28 @@ 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) + 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; } @@ -1010,6 +1039,7 @@ UnusedVariableRemover::UnusedVariableRemover(): r_assignment(0), assignment_target(false), r_side_effects(false), + in_struct(false), composite_reference(false) { } @@ -1233,8 +1263,19 @@ void UnusedVariableRemover::visit(ExpressionStatement &expr) unused_nodes.insert(&expr); } +void UnusedVariableRemover::visit(StructDeclaration &strct) +{ + SetFlag set_struct(in_struct); + TraversingVisitor::visit(strct); +} + void UnusedVariableRemover::visit(VariableDeclaration &var) { + TraversingVisitor::visit(var); + + if(in_struct) + return; + VariableInfo &var_info = variables[&var]; var_info.interface_block = interface_block; @@ -1250,7 +1291,6 @@ void UnusedVariableRemover::visit(VariableDeclaration &var) var_info.initialized = true; record_assignment(&var, *var.init_expression); } - TraversingVisitor::visit(var); } void UnusedVariableRemover::visit(InterfaceBlock &iface)