diff --git a/TODO b/TODO index da15ec9..8db62c2 100644 --- a/TODO +++ b/TODO @@ -15,7 +15,6 @@ Scripting: * Display errors in UI * Optimizer: * Dead code elimination - * Local variables * Unused arguments * Dead store: call arguments * Unused functions diff --git a/c-opast.hh b/c-opast.hh index b457c96..38ad3de 100644 --- a/c-opast.hh +++ b/c-opast.hh @@ -315,6 +315,9 @@ class A_FuncNode : public A_Node T_String const& getLocalName( const uint32_t index ) const noexcept { return locals_[ index ].name; } + ebcl::T_SRDLocation const& getLocalLocation( + const uint32_t index ) const noexcept + { return locals_[ index ].location; } E_DataType getLocalType( T_String const& name ) const noexcept @@ -327,6 +330,9 @@ class A_FuncNode : public A_Node const uint32_t index , const E_DataType type ) noexcept { locals_[ index ].type = type; } + + void removeLocal( T_String const& name ) noexcept + { locals_.remove( name ); } }; using P_InstrListNode = T_OwnPtr< T_InstrListNode >; diff --git a/c-opopt.cc b/c-opopt.cc index 80cf7d4..13e6b4f 100644 --- a/c-opopt.cc +++ b/c-opopt.cc @@ -1702,6 +1702,51 @@ bool RDCDeadStores_( return changesMade; } +/*----------------------------------------------------------------------------*/ + +bool RDCUnusedLocals_( + T_OpsParserOutput& program , + T_OptData& oData + ) noexcept +{ + M_LOGSTR_( "...... Removing unused locals" , 3 ); + oData.buildUseDefineChains( program ); + + const auto nf{ program.root.nFunctions( ) }; + bool changed{ false }; + for ( auto f = 0u ; f < nf ; f ++ ) { + auto& func{ program.root.function( f ) }; + bool restart{ false }; + for ( auto l = 0u ; l < func.locals( ) ; + restart ? ( restart = false , l = 0 ) : l ++ ) { + + auto const& ln{ func.getLocalName( l ) }; + if ( func.isArgument( ln ) ) { + // TODO + continue; + } + + const T_OptData::T_VarId vid{ + ln , func.name( ) , false + }; + if ( oData.varUDChains.contains( vid ) ) { + continue; + } + oData.logger( [&](){ + T_StringBuilder sb; + sb << "Removing used local variable " + << ln << " at " + << func.getLocalLocation( l ); + return sb; + } , 4 ); + func.removeLocal( ln ); + restart = true; + changed = true; + } + } + return changed; +} + } // namespace /*----------------------------------------------------------------------------*/ @@ -1724,7 +1769,8 @@ bool opopt::RemoveDeadCode( } didStuffThisTime = RDCConditionals_( program , oData ) - || RDCDeadStores_( program , oData ); + || RDCDeadStores_( program , oData ) + || RDCUnusedLocals_( program , oData ); didStuff = didStuff || didStuffThisTime; } while ( didStuffThisTime );