From 3de17b918d88cfcb91e3d755d317c9bd3e5dba32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emmanuel=20Beno=C3=AEt?= Date: Fri, 1 Dec 2017 23:08:05 +0100 Subject: [PATCH] Optimizer - Replace constant inputs with constants --- c-opopt.cc | 23 +++++++++++++++++------ c-sync.cc | 23 +++++++++++++++++++++++ c-sync.hh | 7 +++++++ 3 files changed, 47 insertions(+), 6 deletions(-) diff --git a/c-opopt.cc b/c-opopt.cc index ef8198c..5d44870 100644 --- a/c-opopt.cc +++ b/c-opopt.cc @@ -135,12 +135,23 @@ P_ExpressionNode T_ConstantFolder_::checkExpression( // Replace inputs with value if no curve/constant curve if ( node.type( ) == A_Node::EXPR_INPUT ) { - // TODO: may be replaced with either a constant or a variable. - // * If the curve exists and describes a constant, it's a - // constant - // * If there is no curve and only one default value in the - // whole program then it's also a constant - // * No curve, multiple defaults -> variable + if ( !curves ) { + return {}; + } + + auto& n{ (T_InputExprNode&) node }; + auto const* const curve{ 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 {}; } diff --git a/c-sync.cc b/c-sync.cc index f4b9336..818eff4 100644 --- a/c-sync.cc +++ b/c-sync.cc @@ -214,6 +214,17 @@ float T_SyncSegment::computeValue( return v * ( values[ part + 1 ] - sv ) + sv; } +T_Optional< float > T_SyncSegment::isConstant( ) const noexcept +{ + const float f{ values[ 0 ] }; + for ( auto v : values ) { + if ( f != v ) { + return {}; + } + } + return f; +} + M_LSHIFT_OP( T_StringBuilder , T_SyncSegment::E_SegmentType ) { switch ( value ) { @@ -297,6 +308,18 @@ uint32_t T_SyncCurve::points( ) const noexcept return np; } +T_Optional< float > T_SyncCurve::isConstant( ) const noexcept +{ + T_Optional< float > v; + for ( auto const& s : segments ) { + v = s.isConstant( ); + if ( !v ) { + break; + } + } + return v; +} + /*= T_SyncCurves =============================================================*/ diff --git a/c-sync.hh b/c-sync.hh index 59326f7..11ee17e 100644 --- a/c-sync.hh +++ b/c-sync.hh @@ -48,6 +48,9 @@ struct T_SyncSegment // Compute the value for the specified position, which is relative // to the start of the segment. float computeValue( float relTimeUnits ) const noexcept; + + // Is the segment constant? If it is, return the value. + T_Optional< float > isConstant( ) const noexcept; }; M_LSHIFT_OP( T_StringBuilder , T_SyncSegment::E_SegmentType ); @@ -106,6 +109,10 @@ struct T_SyncCurve // inside a segment, or the first and last value in the curve, or // a junction between segments. uint32_t points( ) const noexcept; + + // Does the curve represent a constant? It does if all values in + // all segments are identical; in that case the value is returned. + T_Optional< float > isConstant( ) const noexcept; }; /*----------------------------------------------------------------------------*/