Optimizer - Some progress on building UD chains
From the table of variables we build a table of per-instruction uses/defines.
This commit is contained in:
parent
5ecc95766a
commit
be007f8f96
1 changed files with 68 additions and 16 deletions
84
c-opopt.cc
84
c-opopt.cc
|
@ -517,6 +517,59 @@ void BUDCVisitor_(
|
|||
}
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
struct T_UDEntry_
|
||||
{
|
||||
uint32_t entry;
|
||||
bool isUse;
|
||||
uint32_t index;
|
||||
};
|
||||
|
||||
using T_UDEPerInstr_ = T_KeyValueTable< uint32_t , T_AutoArray< T_UDEntry_ , 8 > >;
|
||||
|
||||
template< uint32_t S >
|
||||
void BUDCAddEntries_(
|
||||
T_UDEPerInstr_& out ,
|
||||
const uint32_t mainEntry ,
|
||||
const bool isUse ,
|
||||
T_AutoArray< T_OptData::T_VarUDRecord , S > const& entries ) noexcept
|
||||
{
|
||||
const auto na{ entries.size( ) };
|
||||
for ( auto j = 0u ; j < na ; j ++ ) {
|
||||
auto const& use{ entries[ j ] };
|
||||
auto* rec{ out.get( use.node ) };
|
||||
if ( !rec ) {
|
||||
out.add( use.node , T_AutoArray< T_UDEntry_ , 8 >{ } );
|
||||
rec = out.get( use.node );
|
||||
}
|
||||
assert( rec );
|
||||
|
||||
auto& ne{ rec->addNew( ) };
|
||||
ne.entry = mainEntry;
|
||||
ne.isUse = isUse;
|
||||
ne.index = j;
|
||||
}
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
struct T_VarEvt_
|
||||
{
|
||||
enum E_VarEvt {
|
||||
DEF , USE , KILL
|
||||
};
|
||||
|
||||
uint32_t instrId;
|
||||
E_VarEvt evt;
|
||||
T_OptData::T_VarId var;
|
||||
|
||||
T_VarEvt_( uint32_t instrId , E_VarEvt evt ,
|
||||
T_OptData::T_VarId const& var )
|
||||
: instrId( instrId ) , evt( evt ) , var( var )
|
||||
{ }
|
||||
};
|
||||
|
||||
|
||||
} // namespace <anon>
|
||||
|
||||
|
@ -528,28 +581,27 @@ void T_OptData::buildUseDefineChains(
|
|||
M_LOGSTR_( "Building use/define chains" , LL1 );
|
||||
varUDChains.clear( );
|
||||
|
||||
/*
|
||||
* We need to locate all variable uses. For each use, we will go
|
||||
* backwards in the graph, until one of the following becomes true:
|
||||
* - we find an instruction that sets the variable;
|
||||
* - we find the initial block due to cycling back;
|
||||
* - we reached the CFG_ENTER node.
|
||||
* In the latter case, it's an error - the variable is never set.
|
||||
*
|
||||
* FIXME: Nope, actually that won't work. We need to find (set)
|
||||
* instuctions, calls, and also resource initialisations as well
|
||||
* when visiting the tree; *then* we can associate records from
|
||||
* both lists.
|
||||
*
|
||||
* Note: for function arguments, most of this can be avoided by simply
|
||||
* looking at the call sites.
|
||||
*/
|
||||
// Find all definitions and uses, add them to the table
|
||||
visitor.visit( program.root , [&]( auto& n , const bool exit ) {
|
||||
if ( !exit ) {
|
||||
BUDCVisitor_( program.root , *this , n );
|
||||
}
|
||||
return true;
|
||||
} );
|
||||
|
||||
// Build a table of all variable uses/defines that were identified
|
||||
T_UDEPerInstr_ udPerInstr;
|
||||
auto const& udcEntries{ varUDChains.values( ) };
|
||||
const auto n{ udcEntries.size( ) };
|
||||
for ( auto i = 0u ; i < n ; i ++ ) {
|
||||
auto const& r{ udcEntries[ i ] };
|
||||
BUDCAddEntries_( udPerInstr , i , true , r.uses );
|
||||
BUDCAddEntries_( udPerInstr , i , false , r.defines );
|
||||
}
|
||||
|
||||
// For each node of the CFG graph, we need to generate a sequence that
|
||||
// indicates what gets defined, used or killed.
|
||||
T_MultiArray< T_VarEvt_ > cfgVarEvents;
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue