X-Git-Url: http://git.tdb.fi/?p=libs%2Fgl.git;a=blobdiff_plain;f=source%2Fprogramcompiler.cpp;h=1f014f72c654d3e678f706cfff28f9d5173407f4;hp=1c84a96dc925f18095368d63aa13aaaf19a7d88d;hb=aa9873652630db493b5bd9faee4117e9c30ef226;hpb=91d3eac06389c0bb0363f643790581403b5fca1b diff --git a/source/programcompiler.cpp b/source/programcompiler.cpp index 1c84a96d..1f014f72 100644 --- a/source/programcompiler.cpp +++ b/source/programcompiler.cpp @@ -557,8 +557,12 @@ void ProgramCompiler::Formatter::visit(Iteration &iter) void ProgramCompiler::Formatter::visit(Return &ret) { - formatted += "return "; - ret.expression->visit(*this); + formatted += "return"; + if(ret.expression) + { + formatted += ' '; + ret.expression->visit(*this); + } formatted += ';'; } @@ -1171,6 +1175,12 @@ void ProgramCompiler::FunctionInliner::visit(BinaryExpression &binary) inline_result = 0; } +void ProgramCompiler::FunctionInliner::visit(MemberAccess &memacc) +{ + visit_and_inline(memacc.left); + inline_result = 0; +} + void ProgramCompiler::FunctionInliner::visit(FunctionCall &call) { for(vector >::iterator i=call.arguments.begin(); i!=call.arguments.end(); ++i) @@ -1289,7 +1299,8 @@ void ProgramCompiler::ExpressionEvaluator::visit(BinaryExpression &binary) ProgramCompiler::ConstantConditionEliminator::ConstantConditionEliminator(): - scope_level(0) + scope_level(0), + record_only(false) { } void ProgramCompiler::ConstantConditionEliminator::visit(Block &block) @@ -1301,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); @@ -1314,28 +1332,49 @@ void ProgramCompiler::ConstantConditionEliminator::visit(VariableDeclaration &va void ProgramCompiler::ConstantConditionEliminator::visit(Conditional &cond) { - ExpressionEvaluator eval(variable_values); - 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) { - if(iter.condition) + if(!record_only) { - ExpressionEvaluator eval; - 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); } TraversingVisitor::visit(iter); + + if(VariableDeclaration *init_decl = dynamic_cast(iter.init_statement.get())) + variable_values.erase(init_decl); }