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 ===================================================================*/
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
// constants, data types, etc...)
struct T_OpsParserOutput
@ -19,12 +22,22 @@ struct T_OpsParserOutput
class T_OpsParser : public ebcl::A_PrivateImplementation
{
private:
F_OPLogger logger_{ []( auto , auto ) { } };
T_Array< ebcl::T_SRDError > errors_;
T_OwnPtr< T_OpsParserOutput > output_;
public:
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;
T_Array< ebcl::T_SRDError > const& errors( ) const noexcept

View file

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

View file

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

View file

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

View file

@ -2,6 +2,7 @@
#include "c-opast.hh"
#include "c-ops.hh"
#include "c-opcomp.hh"
#include "c-opopt.hh"
#include <ebcl/Files.hh>
#include <ebcl/SRDText.hh>
#include <ebcl/Algorithms.hh>
@ -42,6 +43,16 @@ void WriteSRDError(
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
const T_String inputName( argc >= 2 ? argv[ 1 ] : "demo.srd" );
T_File input( inputName , E_FileMode::READ_ONLY );
@ -73,14 +84,10 @@ int main( int argc , char** argv )
return 2;
}
// Parse the fuck
// Parse
T_OpsParser parser;
if ( parser.parse( srdOut.list( ) ) ) {
printf( "Parser successful. Compiling...\n" );
T_OpsCompiler compiler;
compiler.compile( *parser.result( ) );
return 0;
} else {
parser.setLogger( logger );
if ( !parser.parse( srdOut.list( ) ) ) {
T_StringBuilder sb;
for ( auto const& err : parser.errors( ) ) {
WriteSRDError( sb , err );
@ -89,4 +96,20 @@ int main( int argc , char** argv )
fprintf( stderr , "%s" , sb.data( ) );
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;
}