Builder tool - Various, pre-constant propagation

+ Prepared flags for constant propagation
+ UI instructions removal in compiler
+ Various changes to test "demo"
This commit is contained in:
Emmanuel BENOîT 2017-12-03 14:59:39 +01:00
parent c4ce6e90d7
commit c7e4ccf67e
9 changed files with 104 additions and 52 deletions

View file

@ -79,6 +79,22 @@ bool BCLResolutions_( T_SRDParserData const& data )
/*----------------------------------------------------------------------------*/
F_SRDHandler BCLToggle_(
ptrdiff_t const fldOffset ) noexcept
{
return [=]( T_SRDParserData const& d ) -> bool {
auto const& in{ *d.input };
char* bCfg{ (char*) &d.currentData->value< T_BuildConfiguration >( ) };
*(bool*)( bCfg + fldOffset ) = ( in[ 1 ].stringValue( ) == "on" );
return true;
};
}
#define M_BCL_TOGGLE_( N ) \
BCLToggle_( offsetof( T_BuildConfiguration , N ) )
/*----------------------------------------------------------------------------*/
T_SRDParserConfig BCLInitDefinitions_( ) noexcept
{
using namespace ebcl::SRD;
@ -116,40 +132,20 @@ T_SRDParserConfig BCLInitDefinitions_( ) noexcept
defs.context( "optim" )
<< ( Rule( ) << "constant-folding" << "off"
<< []( T_SRDParserData const& d ) -> bool {
auto& bCfg{ d.currentData->value< T_BuildConfiguration >( ) };
bCfg.constantFolding = false;
return true;
} )
<< M_BCL_TOGGLE_( constantFolding ) )
<< ( Rule( ) << "constant-folding" << "on" << EnterContext( "opt-cf" )
<< []( T_SRDParserData const& d ) -> bool {
auto& bCfg{ d.currentData->value< T_BuildConfiguration >( ) };
bCfg.constantFolding = true;
return true;
} )
<< M_BCL_TOGGLE_( constantFolding ) )
<< ( Rule( ) << "constant-propagation" << Enum( "on-off" )
<< M_BCL_TOGGLE_( constantPropagation ) )
<< ( Rule( ) << "dead-code-elimination" << Enum( "on-off" )
<< []( T_SRDParserData const& d ) -> bool {
auto& bCfg{ d.currentData->value< T_BuildConfiguration >( ) };
bCfg.deadCodeElimination = true;
return true;
} )
<< M_BCL_TOGGLE_( deadCodeElimination ) )
;
defs.context( "opt-cf" )
<< ( Rule( ) << "fixed-resolution" << Enum( "on-off" )
<< []( T_SRDParserData const& d ) -> bool {
auto const& in{ *d.input };
auto& bCfg{ d.currentData->value< T_BuildConfiguration >( ) };
bCfg.cfFixedSize = ( in[ 1 ].stringValue( ) == "on" );
return true;
} )
<< M_BCL_TOGGLE_( cfFixedSize ) )
<< ( Rule( ) << "inputs" << Enum( "on-off" )
<< []( T_SRDParserData const& d ) -> bool {
auto const& in{ *d.input };
auto& bCfg{ d.currentData->value< T_BuildConfiguration >( ) };
bCfg.cfInputs = ( in[ 1 ].stringValue( ) == "on" );
return true;
} )
<< M_BCL_TOGGLE_( cfInputs ) )
;
return T_SRDParserConfig{ defs };

View file

@ -27,6 +27,10 @@ struct T_BuildConfiguration
// Get rid of (get-input) for constant or undefined curves
bool cfInputs{ false };
// Constant propagation ------------------------------------------------
bool constantPropagation{ false };
// Dead code elimination -----------------------------------------------
bool deadCodeElimination{ false };

View file

@ -16,13 +16,17 @@ namespace {
struct T_CompilerImpl_
{
T_CompilerImpl_( F_OPLogger* logger ) noexcept
: logger( *logger ) {}
T_CompilerImpl_( F_OPLogger* const logger ,
const bool noUIInstructions ) noexcept
: logger( *logger ) , noUIInstructions( noUIInstructions )
{}
P_OpProgram compile( T_OpsParserOutput const& input ) noexcept;
private:
F_OPLogger& logger;
const bool noUIInstructions;
T_Visitor< A_Node > astVisitor{ ASTVisitorBrowser };
T_Set< uint32_t > constants{ UseTag< IndexBacked< > >( ) };
T_KeyValueTable< T_String , uint32_t > locations;
@ -650,6 +654,9 @@ bool T_CompilerImpl_::compileNode(
//- DEBUGGING / UI CONTROLS -----------------------------------------------------------
case A_Node::OP_PROFILE:
if ( noUIInstructions ) {
break;
}
if ( exit ) {
addInstruction( OP_UI_PEXIT , node.location( ) );
} else {
@ -663,6 +670,9 @@ bool T_CompilerImpl_::compileNode(
break;
case A_Node::OP_INPUT:
if ( noUIInstructions ) {
break;
}
if ( exit ) {
auto& in( (T_InputInstrNode&) node );
T_OpValue value;
@ -675,6 +685,9 @@ bool T_CompilerImpl_::compileNode(
break;
case A_Node::OP_ODBG:
if ( noUIInstructions ) {
break;
}
if ( exit ) {
auto& n( (T_OutputDebugInstrNode&) node );
if ( ! output->uiStrings.contains( n.description( ) ) ) {
@ -689,6 +702,9 @@ bool T_CompilerImpl_::compileNode(
break;
case A_Node::OP_OVERRIDES:
if ( noUIInstructions ) {
break;
}
if ( exit ) {
auto& n{ (T_OverridesInstrNode&) node };
const auto idx{ output->overrides.add( n.extractRoot( ) ) };
@ -917,8 +933,9 @@ void T_CompilerImpl_::applyStackEffects(
/*= T_OpsCompiler ==============================================================*/
T_OpsCompiler::T_OpsCompiler( ) noexcept
: A_PrivateImplementation( new T_CompilerImpl_( &logger_ ) )
T_OpsCompiler::T_OpsCompiler(
const bool noUIInstructions ) noexcept
: A_PrivateImplementation( new T_CompilerImpl_( &logger_ , noUIInstructions ) )
{ }
P_OpProgram T_OpsCompiler::compile(

View file

@ -57,7 +57,7 @@ class T_OpsCompiler : public ebcl::A_PrivateImplementation
F_OPLogger logger_{ []( auto , auto ) { } };
public:
T_OpsCompiler( ) noexcept;
T_OpsCompiler( bool noUIInstructions = false ) noexcept;
void setLogger( F_OPLogger logger )
{

View file

@ -392,6 +392,27 @@ bool opopt::FoldConstants(
}
/*= CONSTANT PROPAGATION =====================================================*/
bool opopt::PropagateConstants(
T_OpsParserOutput& program ,
T_OptData& optData ) noexcept
{
// We need to follow the general execution flow of the program. This is
// not as straightforward as it seems.
// - Handling locals is rather easy as they "die" at the end of
// the function in which they are defined.
// - Handling variables in init and functions that are called only
// from init is not too hard: once a variable is set to a constant, it
// can be substituted until the next set instruction.
// - Other variables need additional checks before propagating.
// For example, if a variable is set to a constant during init, but is
// updated at the end of the frame function, the value cannot be
// propagated.
return false;
}
/*= DEAD CODE REMOVAL ========================================================*/
bool opopt::RemoveDeadCode(

View file

@ -39,18 +39,28 @@ struct T_OptData
void findInputDecls( T_OpsParserOutput& program ) noexcept;
};
/*----------------------------------------------------------------------------*/
// Attempts to fold constant expressions into single constants. Returns true if
// transformations were made, false if not.
/*= INDIVIDUAL OPTIMISATIONS =================================================*/
// All functions below return true if transformations were made, false if not.
// Attempts to fold constant expressions into single constants.
//
bool FoldConstants( T_OpsParserOutput& program ,
bool FoldConstants(
T_OpsParserOutput& program ,
T_OptData& optData ) noexcept;
// Attempts to propagate values from variables that contain constants to the
// locations at which they are used.
//
bool PropagateConstants(
T_OpsParserOutput& program ,
T_OptData& optData ) noexcept;
// Attempt to remove blocks of code that will not be executed because of
// constant conditions. Returns true if transformations were made, false if not.
// constant conditions.
//
bool RemoveDeadCode( T_OpsParserOutput& program ,
bool RemoveDeadCode(
T_OpsParserOutput& program ,
T_OptData& optData ) noexcept;

View file

@ -132,7 +132,7 @@ int main( int argc , char** argv )
break;
case 'c':
if ( oSrcPath ) {
if ( oBuildCfg ) {
fprintf( stderr , "Duplicate build configuration\n" );
return EXIT_FAILURE;
}
@ -252,22 +252,18 @@ int main( int argc , char** argv )
bool doneStuff;
do {
doneStuff = false;
if ( cfg.constantFolding ) {
while ( opopt::FoldConstants( *parsed , od ) ) {
doneStuff = true;
}
if ( cfg.constantFolding && opopt::FoldConstants( *parsed , od ) ) {
doneStuff = true;
}
if ( cfg.deadCodeElimination ) {
while ( opopt::RemoveDeadCode( *parsed , od ) ) {
doneStuff = true;
}
if ( cfg.deadCodeElimination && opopt::RemoveDeadCode( *parsed , od ) ) {
doneStuff = true;
}
} while ( doneStuff );
}
// Compile
M_LOGSTR( "Compiling script" , 1 );
T_OpsCompiler compiler;
T_OpsCompiler compiler( true );
compiler.setLogger( logger );
compiler.compile( *parsed );
return 0;

View file

@ -1,4 +1,4 @@
(cfg "Default"
(cfg "Optimized"
(resolutions
(1280 720)
(1920 1080)
@ -7,3 +7,11 @@
(constant-folding on)
)
)
(cfg "Basic"
(resolutions
(1280 720)
(1920 1080)
)
(optimizer off)
)

View file

@ -1,7 +1,7 @@
(duration 0.133333 450)
(camera-nearplane
(segment linear
(segment smooth
(values 1.1547 1.1547 4.82843)
(durations 225 225)
)
@ -9,7 +9,7 @@
(camera-pos-x
(segment linear
(values -300 -150 0)
(values -4000 -2000 0)
(durations 225 225)
)
)
@ -51,7 +51,7 @@
(camera-lookat-x
(segment linear
(values -300 -150 0)
(values -4000 -2000 0)
(durations 225 225)
)
)