diff --git a/TODO b/TODO index 36d7f33..c94bd3e 100644 --- a/TODO +++ b/TODO @@ -14,8 +14,6 @@ Scripting: * Aliases * Display errors in UI * Optimizer: - * Constant propagation - * Call arguments * Dead code elimination * Local variables * Unused arguments diff --git a/c-opopt.cc b/c-opopt.cc index 3f68de4..4825446 100644 --- a/c-opopt.cc +++ b/c-opopt.cc @@ -1573,5 +1573,49 @@ bool opopt::RemoveDeadCode( T_OpsParserOutput& program , T_OptData& oData ) noexcept { + oData.buildUseDefineChains( program ); + M_LOGSTR_( "... Eliminating dead code" , 2 ); + + struct T_ConstCond_ { + T_CondInstrNode* node; + int64_t value; + }; + T_AutoArray< T_ConstCond_ , 16 > constConds; + oData.visitor.visit( program.root , [&]( A_Node& node , const bool exit ) { + const auto nt{ node.type( ) }; + + if ( !exit && nt == A_Node::OP_COND ) { + auto& cn{ dynamic_cast< T_CondInstrNode& >( node ) }; + auto const& ce{ cn.expression( ).expression( ) }; + if ( ce.type( ) == A_Node::EXPR_CONST ) { + const int64_t ccv{ ( (T_ConstantExprNode const&) ce ).intValue( ) }; + constConds.add( T_ConstCond_{ &cn , ccv } ); + return false; + } + } + + return !dynamic_cast< A_ExpressionNode* >( &node ); + } ); + + if ( constConds.size( ) ) { + const auto ncc{ constConds.size( ) }; + for ( auto i = 0u ; i < ncc ; i ++ ) { + auto const& cc{ constConds[ i ] }; + auto& cn{ *cc.node }; + T_InstrListNode* replacement; + printf( "IF (CNST: %ld)!!!\n" , cc.value ); + if ( cn.hasCase( cc.value ) ) { + printf( "Will replace with case\n" ); + replacement = &cn.getCase( cc.value ).instructions( ); + } else if ( cn.hasDefaultCase( ) ) { + printf( "Will replace with default\n" ); + replacement = &cn.defaultCase( ).instructions( ); + } else { + printf( "DELETE! DELETE! DELETE!\n" ); + replacement = nullptr; + } + } + } + return false; } diff --git a/test/build.srd b/test/build.srd index d58c2ea..221bc78 100644 --- a/test/build.srd +++ b/test/build.srd @@ -8,6 +8,7 @@ (fixed-resolution on) ) (constant-propagation on) + (dead-code-elimination on) ) )