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;
|
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 =========================================================*/
|
/*= CONSTANT FOLDING =========================================================*/
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
@ -43,6 +68,12 @@ struct T_ConstantFolder_
|
||||||
P_ExpressionNode doIdExpr(
|
P_ExpressionNode doIdExpr(
|
||||||
T_IdentifierExprNode& node ) noexcept;
|
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.
|
// Transform an unary operator applied to a constant into a constant.
|
||||||
P_ExpressionNode doUnaryOp(
|
P_ExpressionNode doUnaryOp(
|
||||||
T_UnaryOperatorNode& node ,
|
T_UnaryOperatorNode& node ,
|
||||||
|
@ -126,24 +157,7 @@ P_ExpressionNode T_ConstantFolder_::checkExpression(
|
||||||
|
|
||||||
// Replace inputs with value if no curve/constant curve
|
// Replace inputs with value if no curve/constant curve
|
||||||
if ( node.type( ) == A_Node::EXPR_INPUT ) {
|
if ( node.type( ) == A_Node::EXPR_INPUT ) {
|
||||||
if ( !oData.curves ) {
|
return doInputExpr( (T_InputExprNode&) node );
|
||||||
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 {};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Replace UnOp( Cnst ) with result
|
// 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(
|
P_ExpressionNode T_ConstantFolder_::doIdExpr(
|
||||||
T_IdentifierExprNode& node ) noexcept
|
T_IdentifierExprNode& node ) noexcept
|
||||||
{
|
{
|
||||||
|
@ -321,6 +363,9 @@ bool opopt::FoldConstants(
|
||||||
T_OptData& oData ) noexcept
|
T_OptData& oData ) noexcept
|
||||||
{
|
{
|
||||||
T_ConstantFolder_ folder{ oData };
|
T_ConstantFolder_ folder{ oData };
|
||||||
|
if ( oData.curves ) {
|
||||||
|
oData.findInputDecls( program );
|
||||||
|
}
|
||||||
oData.visitor.visit( program.root , folder );
|
oData.visitor.visit( program.root , folder );
|
||||||
return folder.didFold;
|
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
|
// A visitor to be used for the tree
|
||||||
ebcl::T_Visitor< opast::A_Node > visitor{ opast::ASTVisitorBrowser };
|
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