X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fglsl%2Foptimize.cpp;h=63dfcb5c2823758dc054f92cb4d1960650e05d44;hb=188b3b2bf686aada8772475aabf899a0420cbd0f;hp=0f765c2a4aa6ce23edd99f2dd0fed35e4041bd3c;hpb=305b62cf4f7e2a4ca3cc56109003aed6bde61c25;p=libs%2Fgl.git diff --git a/source/glsl/optimize.cpp b/source/glsl/optimize.cpp index 0f765c2a..63dfcb5c 100644 --- a/source/glsl/optimize.cpp +++ b/source/glsl/optimize.cpp @@ -138,7 +138,7 @@ string InlineContentInjector::apply(Stage &stage, FunctionDeclaration &target_fu staging_block.parent = &tgt_blk; staging_block.variables.clear(); - std::vector > params; + vector > params; params.reserve(source_func->parameters.size()); for(NodeArray::iterator i=source_func->parameters.begin(); i!=source_func->parameters.end(); ++i) { @@ -553,18 +553,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) { @@ -623,20 +611,18 @@ 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()); + else + { + r_constant = false; + return; + } literal->value = r_constant_value; expr = literal; } @@ -678,25 +664,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,45 +704,43 @@ 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) + if(!left_value.check_type()) return; if(oper=='%') @@ -907,6 +893,52 @@ void ConstantConditionEliminator::visit(Iteration &iter) } +UnreachableCodeRemover::UnreachableCodeRemover(): + reachable(true) +{ } + +bool UnreachableCodeRemover::apply(Stage &stage) +{ + stage.content.visit(*this); + NodeRemover().apply(stage, unreachable_nodes); + return !unreachable_nodes.empty(); +} + +void UnreachableCodeRemover::visit(Block &block) +{ + NodeList::iterator i = block.body.begin(); + for(; (reachable && i!=block.body.end()); ++i) + (*i)->visit(*this); + for(; i!=block.body.end(); ++i) + unreachable_nodes.insert(i->get()); +} + +void UnreachableCodeRemover::visit(FunctionDeclaration &func) +{ + TraversingVisitor::visit(func); + reachable = true; +} + +void UnreachableCodeRemover::visit(Conditional &cond) +{ + cond.body.visit(*this); + bool reachable_if_true = reachable; + reachable = true; + cond.else_body.visit(*this); + + reachable |= reachable_if_true; +} + +void UnreachableCodeRemover::visit(Iteration &iter) +{ + TraversingVisitor::visit(iter); + + /* Always consider code after a loop reachable, since there's no checking + for whether the loop executes. */ + reachable = true; +} + + bool UnusedTypeRemover::apply(Stage &stage) { stage.content.visit(*this); @@ -964,6 +996,7 @@ UnusedVariableRemover::UnusedVariableRemover(): r_assignment(0), assignment_target(false), r_side_effects(false), + in_struct(false), composite_reference(false) { } @@ -1187,8 +1220,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; @@ -1204,7 +1248,6 @@ void UnusedVariableRemover::visit(VariableDeclaration &var) var_info.initialized = true; record_assignment(&var, *var.init_expression); } - TraversingVisitor::visit(var); } void UnusedVariableRemover::visit(InterfaceBlock &iface)