Builder tool - Logging

This commit is contained in:
Emmanuel BENOîT 2017-12-02 12:18:31 +01:00
parent ffcf2917d5
commit 3986bd5386
5 changed files with 93 additions and 27 deletions

View file

@ -7,6 +7,9 @@
/*= PARSER ===================================================================*/ /*= PARSER ===================================================================*/
using F_OPGenLog = std::function< T_StringBuilder( ) >;
using F_OPLogger = std::function< void( F_OPGenLog , uint32_t ) >;
// Parser output. Consists in a root node as well as other details (table of // Parser output. Consists in a root node as well as other details (table of
// constants, data types, etc...) // constants, data types, etc...)
struct T_OpsParserOutput struct T_OpsParserOutput
@ -19,12 +22,22 @@ struct T_OpsParserOutput
class T_OpsParser : public ebcl::A_PrivateImplementation class T_OpsParser : public ebcl::A_PrivateImplementation
{ {
private: private:
F_OPLogger logger_{ []( auto , auto ) { } };
T_Array< ebcl::T_SRDError > errors_; T_Array< ebcl::T_SRDError > errors_;
T_OwnPtr< T_OpsParserOutput > output_; T_OwnPtr< T_OpsParserOutput > output_;
public: public:
T_OpsParser( ) noexcept; T_OpsParser( ) noexcept;
void setLogger( F_OPLogger logger )
{
if ( logger ) {
logger_ = std::move( logger );
} else {
logger_ = []( auto , auto ) { };
}
}
bool parse( ebcl::T_SRDList const& input ) noexcept; bool parse( ebcl::T_SRDList const& input ) noexcept;
T_Array< ebcl::T_SRDError > const& errors( ) const noexcept T_Array< ebcl::T_SRDError > const& errors( ) const noexcept

View file

@ -1,6 +1,5 @@
#include "externals.hh" #include "externals.hh"
#include "c-opcomp.hh"
#include "c-opopt.hh" #include "c-opopt.hh"
#include "c-ops.hh" #include "c-ops.hh"
#include "c-sync.hh" #include "c-sync.hh"
@ -134,8 +133,14 @@ template<
std::function< void( T& , P_ExpressionNode ) > set ) noexcept std::function< void( T& , P_ExpressionNode ) > set ) noexcept
{ {
auto& node{ (T&) n }; auto& node{ (T&) n };
auto r{ checkExpression( get( node ) ) }; auto& child{ get( node ) };
auto r{ checkExpression( child ) };
if ( r ) { if ( r ) {
oData.logger( [&]() {
T_StringBuilder sb;
sb << "substituting node at " << child.location( );
return sb;
} , 2 );
r->location( ) = node.location( ); r->location( ) = node.location( );
set( node , std::move( r ) ); set( node , std::move( r ) );
didFold = true; didFold = true;
@ -230,11 +235,17 @@ P_ExpressionNode T_ConstantFolder_::doIdExpr(
} }
if ( node.id( ) == "width" ) { if ( node.id( ) == "width" ) {
oData.logger( []{
return T_StringBuilder{ "replacing $width with fixed width" };
} , 2 );
return NewOwned< T_ConstantExprNode >( node.parent( ) , return NewOwned< T_ConstantExprNode >( node.parent( ) ,
double( oData.fixedSize->first ) ); double( oData.fixedSize->first ) );
} }
if ( node.id( ) == "height" ) { if ( node.id( ) == "height" ) {
oData.logger( []{
return T_StringBuilder{ "replacing $height with fixed height" };
} , 2 );
return NewOwned< T_ConstantExprNode >( node.parent( ) , return NewOwned< T_ConstantExprNode >( node.parent( ) ,
float( oData.fixedSize->second ) ); float( oData.fixedSize->second ) );
} }
@ -363,10 +374,20 @@ bool opopt::FoldConstants(
T_OptData& oData ) noexcept T_OptData& oData ) noexcept
{ {
T_ConstantFolder_ folder{ oData }; T_ConstantFolder_ folder{ oData };
oData.logger( []() {
return T_StringBuilder{ "constant folding pass" };
} , 1 );
if ( oData.curves ) { if ( oData.curves ) {
oData.findInputDecls( program ); oData.findInputDecls( program );
} }
oData.visitor.visit( program.root , folder ); oData.visitor.visit( program.root , [&]( auto& n , auto x ) {
return folder( n , x );
} );
oData.logger( [&]() {
return T_StringBuilder{
folder.didFold ? "some constants were folded"
: "no constants were folded" };
} , 1 );
return folder.didFold; return folder.didFold;
} }

View file

@ -1,9 +1,9 @@
#pragma once #pragma once
#include "c-opast.hh" #include "c-opast.hh"
#include "c-opcomp.hh"
#include <ebcl/Algorithms.hh> #include <ebcl/Algorithms.hh>
struct T_OpsParserOutput;
struct T_SyncCurves; struct T_SyncCurves;
namespace opopt { namespace opopt {
@ -11,6 +11,9 @@ namespace opopt {
// Persistent data for the various stages of the optimizer. // Persistent data for the various stages of the optimizer.
struct T_OptData struct T_OptData
{ {
// Logger
F_OPLogger logger{ []( auto , auto ) {} };
// List of errors generated by the optimizer // List of errors generated by the optimizer
T_Array< ebcl::T_SRDError > errors; T_Array< ebcl::T_SRDError > errors;
@ -19,7 +22,7 @@ struct T_OptData
T_Optional< std::pair< uint32_t , uint32_t > > fixedSize; T_Optional< std::pair< uint32_t , uint32_t > > fixedSize;
// The curves that will be bound to the inputs. // The curves that will be bound to the inputs.
T_SyncCurves const* curves; T_SyncCurves const* curves{ nullptr };
// 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 };

View file

@ -157,6 +157,7 @@ struct T_ParserImpl_
T_OwnPtr< T_OpsParserOutput >& output; T_OwnPtr< T_OpsParserOutput >& output;
T_Array< T_SRDError >& errors; T_Array< T_SRDError >& errors;
F_OPLogger& logger;
T_MultiArray< uint32_t > calls; T_MultiArray< uint32_t > calls;
T_Array< T_InstrRestriction > callInfo; T_Array< T_InstrRestriction > callInfo;
T_SRDParserConfig ovParserConfig; T_SRDParserConfig ovParserConfig;
@ -174,7 +175,8 @@ struct T_ParserImpl_
T_SyncOverrideVisitor ovVisitor; T_SyncOverrideVisitor ovVisitor;
T_ParserImpl_( T_Array< T_SRDError >* errors , T_ParserImpl_( T_Array< T_SRDError >* errors ,
T_OwnPtr< T_OpsParserOutput >* root ) noexcept; T_OwnPtr< T_OpsParserOutput >* root ,
F_OPLogger* logger ) noexcept;
// --------------------------------------------------------------------- // ---------------------------------------------------------------------
@ -304,8 +306,9 @@ struct T_ParserImpl_
inline T_ParserImpl_::T_ParserImpl_( inline T_ParserImpl_::T_ParserImpl_(
T_Array< T_SRDError >* const errors , T_Array< T_SRDError >* const errors ,
T_OwnPtr< T_OpsParserOutput >* const output ) noexcept T_OwnPtr< T_OpsParserOutput >* const output ,
: output( *output ) , errors( *errors ) , F_OPLogger* logger ) noexcept
: output( *output ) , errors( *errors ) , logger( *logger ) ,
ovParserConfig( sov::GetParserConfig( ) ) , ovParserConfig( sov::GetParserConfig( ) ) ,
ovParser( ovParserConfig ) ovParser( ovParserConfig )
{ } { }
@ -531,11 +534,11 @@ bool T_ParserImpl_::collectGlobalTypes( ) noexcept
} }
assert( dt != E_DataType::UNKNOWN ); assert( dt != E_DataType::UNKNOWN );
#ifdef INVASIVE_TRACES logger( [&]{
esb << "id " << id << " as " << dt << " at " << location << '\n' << '\0'; T_StringBuilder sb;
printf( "%s" , esb.data( ) ); sb << "id " << id << " as " << dt << " at " << location;
esb.clear( ); return sb;
#endif } , 2 );
// When we find a set instruction, we need to check whether // When we find a set instruction, we need to check whether
// it is affecting a local variable. If it is we'll just skip // it is affecting a local variable. If it is we'll just skip
@ -586,6 +589,8 @@ bool T_ParserImpl_::collectGlobalTypes( ) noexcept
bool T_ParserImpl_::checkArgumentTypes( ) noexcept bool T_ParserImpl_::checkArgumentTypes( ) noexcept
{ {
logger( []{ return T_StringBuilder{ "Checking argument types" }; } , 1 );
// Find functions for which arguments types need to be resolved // Find functions for which arguments types need to be resolved
const auto nFunctions( output->root.nFunctions( ) ); const auto nFunctions( output->root.nFunctions( ) );
bool argsResolved[ nFunctions ]; bool argsResolved[ nFunctions ];
@ -624,12 +629,12 @@ bool T_ParserImpl_::checkArgumentTypes( ) noexcept
} ); } );
} }
#ifdef INVASIVE_TRACES #define TRACE( x ) \
T_StringBuilder tracer; logger( [&]{ \
#define TRACE( x ) do { tracer.clear( ) << x << '\0'; printf( "%s\n" , tracer.data( ) ); } while (0) T_StringBuilder sb; \
#else sb << x; \
#define TRACE( x ) return sb; \
#endif } , 2 )
T_StringBuilder esb; T_StringBuilder esb;
bool changed = true; bool changed = true;
@ -2039,7 +2044,8 @@ P_ExpressionNode T_ParserImpl_::parseUnaryOp(
/*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/
T_OpsParser::T_OpsParser( ) noexcept T_OpsParser::T_OpsParser( ) noexcept
: A_PrivateImplementation( new T_ParserImpl_( &errors_ , &output_ ) ) , : A_PrivateImplementation( new T_ParserImpl_(
&errors_ , &output_ , &logger_ ) ) ,
errors_( 64 ) , output_{} errors_( 64 ) , output_{}
{} {}

View file

@ -2,6 +2,7 @@
#include "c-opast.hh" #include "c-opast.hh"
#include "c-ops.hh" #include "c-ops.hh"
#include "c-opcomp.hh" #include "c-opcomp.hh"
#include "c-opopt.hh"
#include <ebcl/Files.hh> #include <ebcl/Files.hh>
#include <ebcl/SRDText.hh> #include <ebcl/SRDText.hh>
#include <ebcl/Algorithms.hh> #include <ebcl/Algorithms.hh>
@ -42,6 +43,16 @@ void WriteSRDError(
int main( int argc , char** argv ) int main( int argc , char** argv )
{ {
uint32_t logLevel{ 0 };
const auto logger{ [=]( F_OPGenLog func , uint32_t level ) {
if ( level > logLevel ) {
return;
}
auto sb{ func( ) };
sb << '\0';
printf( "LOG{%d} %s\n" , level , sb.data( ) );
} };
// Open file // Open file
const T_String inputName( argc >= 2 ? argv[ 1 ] : "demo.srd" ); const T_String inputName( argc >= 2 ? argv[ 1 ] : "demo.srd" );
T_File input( inputName , E_FileMode::READ_ONLY ); T_File input( inputName , E_FileMode::READ_ONLY );
@ -73,14 +84,10 @@ int main( int argc , char** argv )
return 2; return 2;
} }
// Parse the fuck // Parse
T_OpsParser parser; T_OpsParser parser;
if ( parser.parse( srdOut.list( ) ) ) { parser.setLogger( logger );
printf( "Parser successful. Compiling...\n" ); if ( !parser.parse( srdOut.list( ) ) ) {
T_OpsCompiler compiler;
compiler.compile( *parser.result( ) );
return 0;
} else {
T_StringBuilder sb; T_StringBuilder sb;
for ( auto const& err : parser.errors( ) ) { for ( auto const& err : parser.errors( ) ) {
WriteSRDError( sb , err ); WriteSRDError( sb , err );
@ -89,4 +96,20 @@ int main( int argc , char** argv )
fprintf( stderr , "%s" , sb.data( ) ); fprintf( stderr , "%s" , sb.data( ) );
return 3; return 3;
} }
auto parsed{ parser.result( ) };
// Optimize
opopt::T_OptData od;
od.logger = logger;
//od.fixedSize = std::make_pair( 1280u , 720u );
bool doneStuff{ false };
do {
doneStuff = opopt::FoldConstants( *parsed , od );
doneStuff = opopt::RemoveDeadCode( *parsed , od ) || doneStuff;
} while ( doneStuff );
// Compile
T_OpsCompiler compiler;
compiler.compile( *parsed );
return 0;
} }