From: Mikko Rasa Date: Sat, 7 Jul 2018 07:25:08 +0000 (+0300) Subject: Be less eager to optimize constant conditions in loops X-Git-Url: http://git.tdb.fi/?a=commitdiff_plain;h=8e14c29;p=libs%2Fgl.git Be less eager to optimize constant conditions in loops It still requires more work to actually detect the scope in which variables are set, but this at least solves the immediate problem I had. --- diff --git a/source/programcompiler.cpp b/source/programcompiler.cpp index 1c84a96d..1a3cd34f 100644 --- a/source/programcompiler.cpp +++ b/source/programcompiler.cpp @@ -1200,12 +1200,14 @@ 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): - variable_values(&v), +ProgramCompiler::ExpressionEvaluator::ExpressionEvaluator(const ValueMap *v, bool c): + variable_values(v), + const_only(c), result(0.0f), result_valid(false) { } @@ -1230,6 +1232,8 @@ void ProgramCompiler::ExpressionEvaluator::visit(VariableReference &var) { if(!var.declaration) return; + if(const_only && !var.declaration->constant) + return; if(variable_values) { @@ -1289,7 +1293,8 @@ void ProgramCompiler::ExpressionEvaluator::visit(BinaryExpression &binary) ProgramCompiler::ConstantConditionEliminator::ConstantConditionEliminator(): - scope_level(0) + scope_level(0), + in_loop(false) { } void ProgramCompiler::ConstantConditionEliminator::visit(Block &block) @@ -1314,7 +1319,7 @@ void ProgramCompiler::ConstantConditionEliminator::visit(VariableDeclaration &va void ProgramCompiler::ConstantConditionEliminator::visit(Conditional &cond) { - ExpressionEvaluator eval(variable_values); + ExpressionEvaluator eval(&variable_values, in_loop); cond.condition->visit(eval); if(eval.result_valid) flatten_block(eval.result ? cond.body : cond.else_body); @@ -1324,9 +1329,10 @@ void ProgramCompiler::ConstantConditionEliminator::visit(Conditional &cond) void ProgramCompiler::ConstantConditionEliminator::visit(Iteration &iter) { + // XXX Should this not visit init_statement first? if(iter.condition) { - ExpressionEvaluator eval; + ExpressionEvaluator eval(0, in_loop); iter.condition->visit(eval); if(eval.result_valid && !eval.result) { @@ -1335,6 +1341,7 @@ void ProgramCompiler::ConstantConditionEliminator::visit(Iteration &iter) } } + SetFlag set_loop(in_loop); TraversingVisitor::visit(iter); } diff --git a/source/programcompiler.h b/source/programcompiler.h index 56bf1d53..d8b2608a 100644 --- a/source/programcompiler.h +++ b/source/programcompiler.h @@ -225,11 +225,12 @@ private: typedef std::map ValueMap; const ValueMap *variable_values; + bool const_only; float result; bool result_valid; ExpressionEvaluator(); - ExpressionEvaluator(const ValueMap &); + ExpressionEvaluator(const ValueMap *, bool); using ProgramSyntax::NodeVisitor::visit; virtual void visit(ProgramSyntax::Literal &); @@ -242,6 +243,7 @@ private: struct ConstantConditionEliminator: BlockModifier { unsigned scope_level; + bool in_loop; ExpressionEvaluator::ValueMap variable_values; ConstantConditionEliminator();