X-Git-Url: http://git.tdb.fi/?p=libs%2Fgl.git;a=blobdiff_plain;f=source%2Fprogramcompiler.cpp;h=1f014f72c654d3e678f706cfff28f9d5173407f4;hp=a1be91ca4f575228fe2f48ccb374fb0097c6dccb;hb=aa9873652630db493b5bd9faee4117e9c30ef226;hpb=e37d3b91500994df3de4fe47bd3d3e75d3104b46 diff --git a/source/programcompiler.cpp b/source/programcompiler.cpp index a1be91ca..1f014f72 100644 --- a/source/programcompiler.cpp +++ b/source/programcompiler.cpp @@ -1210,14 +1210,12 @@ void ProgramCompiler::FunctionInliner::visit(Return &ret) ProgramCompiler::ExpressionEvaluator::ExpressionEvaluator(): variable_values(0), - const_only(false), result(0.0f), result_valid(false) { } -ProgramCompiler::ExpressionEvaluator::ExpressionEvaluator(const ValueMap *v, bool c): - variable_values(v), - const_only(c), +ProgramCompiler::ExpressionEvaluator::ExpressionEvaluator(const ValueMap &v): + variable_values(&v), result(0.0f), result_valid(false) { } @@ -1242,8 +1240,6 @@ void ProgramCompiler::ExpressionEvaluator::visit(VariableReference &var) { if(!var.declaration) return; - if(const_only && !var.declaration->constant) - return; if(variable_values) { @@ -1304,7 +1300,7 @@ void ProgramCompiler::ExpressionEvaluator::visit(BinaryExpression &binary) ProgramCompiler::ConstantConditionEliminator::ConstantConditionEliminator(): scope_level(0), - in_loop(false) + record_only(false) { } void ProgramCompiler::ConstantConditionEliminator::visit(Block &block) @@ -1316,6 +1312,13 @@ void ProgramCompiler::ConstantConditionEliminator::visit(Block &block) variable_values.erase(i->second); } +void ProgramCompiler::ConstantConditionEliminator::visit(UnaryExpression &unary) +{ + if(VariableReference *var = dynamic_cast(unary.expression.get())) + if(unary.oper=="++" || unary.oper=="--") + variable_values.erase(var->declaration); +} + void ProgramCompiler::ConstantConditionEliminator::visit(Assignment &assign) { variable_values.erase(assign.target_declaration); @@ -1329,30 +1332,49 @@ void ProgramCompiler::ConstantConditionEliminator::visit(VariableDeclaration &va void ProgramCompiler::ConstantConditionEliminator::visit(Conditional &cond) { - ExpressionEvaluator eval(&variable_values, in_loop); - cond.condition->visit(eval); - if(eval.result_valid) - flatten_block(eval.result ? cond.body : cond.else_body); - else - TraversingVisitor::visit(cond); + if(!record_only) + { + ExpressionEvaluator eval(variable_values); + cond.condition->visit(eval); + if(eval.result_valid) + { + flatten_block(eval.result ? cond.body : cond.else_body); + return; + } + } + + TraversingVisitor::visit(cond); } void ProgramCompiler::ConstantConditionEliminator::visit(Iteration &iter) { - // XXX Should this not visit init_statement first? - if(iter.condition) + if(!record_only) { - ExpressionEvaluator eval(0, in_loop); - iter.condition->visit(eval); - if(eval.result_valid && !eval.result) + if(iter.condition) { - remove_node = true; - return; + /* If the loop condition is always false on the first iteration, the + entire loop can be removed */ + if(iter.init_statement) + iter.init_statement->visit(*this); + ExpressionEvaluator eval(variable_values); + iter.condition->visit(eval); + if(eval.result_valid && !eval.result) + { + remove_node = true; + return; + } } + + /* Record all assignments that occur inside the loop body so those + variables won't be considered as constant */ + SetFlag set_record(record_only); + TraversingVisitor::visit(iter); } - SetFlag set_loop(in_loop); TraversingVisitor::visit(iter); + + if(VariableDeclaration *init_decl = dynamic_cast(iter.init_statement.get())) + variable_values.erase(init_decl); }