Optimizer - Replace curve-less inputs with single default
This commit is contained in:
parent
f1b51f564d
commit
ffcf2917d5
2 changed files with 74 additions and 18 deletions
81
c-opopt.cc
81
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;
|
||||
}
|
||||
|
|
11
c-opopt.hh
11
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;
|
||||
};
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
|
Loading…
Reference in a new issue