diff --git a/c-opopt.cc b/c-opopt.cc index 62e76aa..3f68de4 100644 --- a/c-opopt.cc +++ b/c-opopt.cc @@ -58,11 +58,11 @@ constexpr uint32_t T_OptData::CFG_END; void T_OptData::findInputDecls( T_OpsParserOutput& program ) noexcept { - if ( inputDecls ) { + if ( state & E_StateItem::INPUTS ) { return; } - inputDecls = T_KeyValueTable< T_String , T_Array< T_InputDecl > >{ }; + inputDecls.clear( ); visitor.visit( program.root , [this]( A_Node& node , const bool exit ) { if ( exit && node.type( ) == A_Node::OP_INPUT ) { auto& input{ (T_InputInstrNode&) node }; @@ -75,6 +75,8 @@ void T_OptData::findInputDecls( } return true; } ); + + state = state | E_StateItem::INPUTS; } @@ -110,6 +112,10 @@ bool ODNIVisitor_( void T_OptData::numberInstructions( T_OpsParserOutput& program ) noexcept { + if ( state & E_StateItem::NUMBERING ) { + return; + } + instructions.clear( ); instrIndex.clear( ); @@ -120,6 +126,8 @@ void T_OptData::numberInstructions( return ODNIVisitor_( node , exit , *this , i ); } ); } + + state = state | E_StateItem::NUMBERING; } uint32_t T_OptData::indexOf( @@ -485,6 +493,11 @@ inline T_StringBuilder BCFGDumpAll_( void T_OptData::buildControlFlowGraph( T_OpsParserOutput& program ) noexcept { + if ( state & E_StateItem::CFG ) { + return; + } + numberInstructions( program ); + // Keep the old array, we'll reuse its contents T_Array< P_CtrlFlowNode > old{ std::move( ctrlFlowGraph ) }; M_LOGSTR_( "Building control flow graph" , 4 ); @@ -511,6 +524,8 @@ void T_OptData::buildControlFlowGraph( logger( [this](){ return BCFGDumpAll_( *this ); } , 6 ); + + state = state | E_StateItem::CFG; } #undef M_ADDNEW_ @@ -1012,6 +1027,11 @@ void BUDCWalkGraph_( void T_OptData::buildUseDefineChains( T_OpsParserOutput& program ) noexcept { + if ( state & E_StateItem::UDCHAINS ) { + return; + } + buildControlFlowGraph( program ); + M_LOGSTR_( "Building use/define chains" , 4 ); varUDChains.clear( ); @@ -1060,6 +1080,8 @@ void T_OptData::buildUseDefineChains( } } } + + state = state | E_StateItem::UDCHAINS; } @@ -1479,8 +1501,6 @@ bool opopt::PropagateConstants( // updated at the end of the frame function, the value cannot be // propagated. - oData.numberInstructions( program ); - oData.buildControlFlowGraph( program ); oData.buildUseDefineChains( program ); M_LOGSTR_( "... Propagating constants" , 2 ); diff --git a/c-opopt.hh b/c-opopt.hh index 583f817..9830deb 100644 --- a/c-opopt.hh +++ b/c-opopt.hh @@ -29,6 +29,19 @@ struct T_OptData //---------------------------------------------------------------------- + // Elements of the optimizer's state + enum class E_StateItem + { + INPUTS , + NUMBERING , + CFG , + UDCHAINS + }; + using T_State = T_Flags< E_StateItem >; + T_State state{}; + + //---------------------------------------------------------------------- + // Table of input declarations; used to fold constant inputs. struct T_InputDecl { ebcl::T_SRDLocation location;