Optimizer - Remove unused local variables

This commit is contained in:
Emmanuel BENOîT 2017-12-17 09:55:53 +01:00
parent ff50ba561a
commit 630dd94ba6
3 changed files with 53 additions and 2 deletions

1
TODO
View file

@ -15,7 +15,6 @@ Scripting:
* Display errors in UI * Display errors in UI
* Optimizer: * Optimizer:
* Dead code elimination * Dead code elimination
* Local variables
* Unused arguments * Unused arguments
* Dead store: call arguments * Dead store: call arguments
* Unused functions * Unused functions

View file

@ -315,6 +315,9 @@ class A_FuncNode : public A_Node
T_String const& getLocalName( T_String const& getLocalName(
const uint32_t index ) const noexcept const uint32_t index ) const noexcept
{ return locals_[ index ].name; } { return locals_[ index ].name; }
ebcl::T_SRDLocation const& getLocalLocation(
const uint32_t index ) const noexcept
{ return locals_[ index ].location; }
E_DataType getLocalType( E_DataType getLocalType(
T_String const& name ) const noexcept T_String const& name ) const noexcept
@ -327,6 +330,9 @@ class A_FuncNode : public A_Node
const uint32_t index , const uint32_t index ,
const E_DataType type ) noexcept const E_DataType type ) noexcept
{ locals_[ index ].type = type; } { locals_[ index ].type = type; }
void removeLocal( T_String const& name ) noexcept
{ locals_.remove( name ); }
}; };
using P_InstrListNode = T_OwnPtr< T_InstrListNode >; using P_InstrListNode = T_OwnPtr< T_InstrListNode >;

View file

@ -1702,6 +1702,51 @@ bool RDCDeadStores_(
return changesMade; 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 <anon> } // namespace <anon>
/*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/
@ -1724,7 +1769,8 @@ bool opopt::RemoveDeadCode(
} }
didStuffThisTime = RDCConditionals_( program , oData ) didStuffThisTime = RDCConditionals_( program , oData )
|| RDCDeadStores_( program , oData ); || RDCDeadStores_( program , oData )
|| RDCUnusedLocals_( program , oData );
didStuff = didStuff || didStuffThisTime; didStuff = didStuff || didStuffThisTime;
} while ( didStuffThisTime ); } while ( didStuffThisTime );