From 8e14c298d9eaa47b81e27d5c25174bda958b445f Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Sat, 7 Jul 2018 10:25:08 +0300 Subject: [PATCH] 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. --- source/programcompiler.cpp | 17 ++++++++++++----- source/programcompiler.h | 4 +++- 2 files changed, 15 insertions(+), 6 deletions(-) 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(); -- 2.43.0