From ffcf2917d507ce0cd71789b6a89b5fb16bb43df0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emmanuel=20Beno=C3=AEt?= Date: Sat, 2 Dec 2017 10:40:47 +0100 Subject: [PATCH] Optimizer - Replace curve-less inputs with single default --- c-opopt.cc | 81 ++++++++++++++++++++++++++++++++++++++++++------------ c-opopt.hh | 11 ++++++++ 2 files changed, 74 insertions(+), 18 deletions(-) diff --git a/c-opopt.cc b/c-opopt.cc index a995579..e6cecb8 100644 --- a/c-opopt.cc +++ b/c-opopt.cc @@ -10,6 +10,31 @@ using namespace opast; using namespace opopt; +/*= T_OptData ================================================================*/ + +void T_OptData::findInputDecls( + T_OpsParserOutput& program ) noexcept +{ + if ( inputDecls ) { + return; + } + + inputDecls = T_KeyValueTable< T_String , T_Array< T_InputDecl > >{ }; + visitor.visit( program.root , [this]( A_Node& node , const bool exit ) { + if ( exit && node.type( ) == A_Node::OP_INPUT ) { + auto& input{ (T_InputInstrNode&) node }; + auto* da{ inputDecls->get( input.id( ) ) }; + if ( !da ) { + inputDecls->add( input.id( ) , T_Array< T_InputDecl >{ } ); + da = inputDecls->get( input.id( ) ); + } + da->add( T_InputDecl{ input.location( ) , input.defValue( ) } ); + } + return true; + } ); +} + + /*= CONSTANT FOLDING =========================================================*/ namespace { @@ -43,6 +68,12 @@ struct T_ConstantFolder_ P_ExpressionNode doIdExpr( T_IdentifierExprNode& node ) noexcept; + // Handle reads from inputs. If there's a curve and it is a constant, + // or if there's no curve and only one default value, then the + // expression is constant. + P_ExpressionNode doInputExpr( + T_InputExprNode& node ) noexcept; + // Transform an unary operator applied to a constant into a constant. P_ExpressionNode doUnaryOp( T_UnaryOperatorNode& node , @@ -126,24 +157,7 @@ P_ExpressionNode T_ConstantFolder_::checkExpression( // Replace inputs with value if no curve/constant curve if ( node.type( ) == A_Node::EXPR_INPUT ) { - if ( !oData.curves ) { - return {}; - } - - auto& n{ (T_InputExprNode&) node }; - auto const* const curve{ oData.curves->curves.get( n.id( ) ) }; - if ( curve ) { - // Curve present, check if it's constant - const auto cval{ curve->isConstant( ) }; - if ( !cval ) { - return {}; - } - return NewOwned< T_ConstantExprNode >( node.parent( ) , *cval ); - } - - // TODO: check whether there's only one default value; if that's the case, - // well, we got ourselves a constant. - return {}; + return doInputExpr( (T_InputExprNode&) node ); } // Replace UnOp( Cnst ) with result @@ -180,6 +194,34 @@ P_ExpressionNode T_ConstantFolder_::checkExpression( /*----------------------------------------------------------------------------*/ +P_ExpressionNode T_ConstantFolder_::doInputExpr( + T_InputExprNode& node ) noexcept +{ + if ( !oData.curves ) { + return {}; + } + + auto const* const curve{ oData.curves->curves.get( node.id( ) ) }; + if ( curve ) { + // Curve present, check if it's constant + const auto cval{ curve->isConstant( ) }; + if ( !cval ) { + return {}; + } + return NewOwned< T_ConstantExprNode >( node.parent( ) , *cval ); + } + + assert( oData.inputDecls ); + auto const* const dva{ oData.inputDecls->get( node.id( ) ) }; + assert( dva ); + if ( dva->size( ) == 1 ) { + // If there's only one default value, that's a constant. + return NewOwned< T_ConstantExprNode >( node.parent( ) , + (*dva)[ 0 ].value ); + } + return {}; +} + P_ExpressionNode T_ConstantFolder_::doIdExpr( T_IdentifierExprNode& node ) noexcept { @@ -321,6 +363,9 @@ bool opopt::FoldConstants( T_OptData& oData ) noexcept { T_ConstantFolder_ folder{ oData }; + if ( oData.curves ) { + oData.findInputDecls( program ); + } oData.visitor.visit( program.root , folder ); return folder.didFold; } diff --git a/c-opopt.hh b/c-opopt.hh index 2e1a600..d42863e 100644 --- a/c-opopt.hh +++ b/c-opopt.hh @@ -23,6 +23,17 @@ struct T_OptData // A visitor to be used for the tree ebcl::T_Visitor< opast::A_Node > visitor{ opast::ASTVisitorBrowser }; + + // Table of input declarations; used to fold constant inputs. + struct T_InputDecl { + ebcl::T_SRDLocation location; + float value; + }; + T_Optional< T_KeyValueTable< T_String , T_Array< T_InputDecl > > > inputDecls; + + //---------------------------------------------------------------------- + + void findInputDecls( T_OpsParserOutput& program ) noexcept; }; /*----------------------------------------------------------------------------*/