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:
Emmanuel BENOîT 2017-12-06 07:42:41 +01:00
parent 5ecc95766a
commit be007f8f96

View file

@ -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;
}