Optimizer - Var use finder refactored
This commit is contained in:
parent
f1ec2cf18c
commit
fa7fba0f98
1 changed files with 75 additions and 62 deletions
137
c-opopt.cc
137
c-opopt.cc
|
@ -356,6 +356,7 @@ void T_OptData::buildControlFlowGraph(
|
||||||
|
|
||||||
|
|
||||||
/*= T_OptData - USE/DEFINE CHAINS ============================================*/
|
/*= T_OptData - USE/DEFINE CHAINS ============================================*/
|
||||||
|
namespace {
|
||||||
|
|
||||||
#warning Remove this later
|
#warning Remove this later
|
||||||
#undef LL1
|
#undef LL1
|
||||||
|
@ -363,6 +364,78 @@ void T_OptData::buildControlFlowGraph(
|
||||||
#define LL1 1
|
#define LL1 1
|
||||||
#define LL2 1
|
#define LL2 1
|
||||||
|
|
||||||
|
void BUDCAddUseRecord_(
|
||||||
|
A_Node& n ,
|
||||||
|
T_OptData& od ,
|
||||||
|
T_RootNode& root ) noexcept
|
||||||
|
{
|
||||||
|
|
||||||
|
// Find instruction and function index
|
||||||
|
auto& nId{ dynamic_cast< T_IdentifierExprNode& >( n ) };
|
||||||
|
A_FuncNode* func{ nullptr };
|
||||||
|
T_Optional< uint32_t > instrId;
|
||||||
|
A_Node* pn{ &nId };
|
||||||
|
while ( pn ) {
|
||||||
|
auto* const asInstr{ dynamic_cast< A_InstructionNode* >( pn ) };
|
||||||
|
func = dynamic_cast< A_FuncNode* >( pn );
|
||||||
|
if ( !instrId && asInstr ) {
|
||||||
|
instrId = od.indexOf( *asInstr );
|
||||||
|
} else if ( func ) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pn = &pn->parent( );
|
||||||
|
}
|
||||||
|
assert( func && instrId );
|
||||||
|
|
||||||
|
// Generate the identifier
|
||||||
|
const T_OptData::T_VarId varId{ [&]() {
|
||||||
|
auto const& n{ nId.id( ) };
|
||||||
|
if ( func->hasLocal( nId.id( ) ) ) {
|
||||||
|
return T_OptData::T_VarId{ n , func->name( ) ,
|
||||||
|
func->isArgument( nId.id( ) ) };
|
||||||
|
}
|
||||||
|
return T_OptData::T_VarId{ n };
|
||||||
|
} () };
|
||||||
|
|
||||||
|
// Access or create the record
|
||||||
|
auto* const varRec{ [&]() {
|
||||||
|
auto* const x{ od.varUDChains.get( varId ) };
|
||||||
|
if ( x ) {
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
od.varUDChains.add( T_OptData::T_VarUseDefine{ varId } );
|
||||||
|
return od.varUDChains.get( varId );
|
||||||
|
} () };
|
||||||
|
assert( varRec );
|
||||||
|
|
||||||
|
// Add use record
|
||||||
|
auto& useRec{ varRec->uses.addNew( ) };
|
||||||
|
useRec.node = *instrId;
|
||||||
|
useRec.fnIndex = root.functionIndex( func->name( ) );
|
||||||
|
|
||||||
|
od.logger( [&](){
|
||||||
|
T_StringBuilder sb;
|
||||||
|
sb << "use " << varId.name << " at " << nId.location( ) << " (";
|
||||||
|
if ( varId.type == T_OptData::E_UDVarType::GLOBAL ) {
|
||||||
|
sb << "global";
|
||||||
|
} else {
|
||||||
|
if ( varId.type == T_OptData::E_UDVarType::LOCAL ) {
|
||||||
|
sb << "local";
|
||||||
|
} else {
|
||||||
|
sb << "argument";
|
||||||
|
}
|
||||||
|
sb << " of " << varId.owner;
|
||||||
|
}
|
||||||
|
sb << ')';
|
||||||
|
return sb;
|
||||||
|
} , LL2 );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace <anon>
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
void T_OptData::buildUseDefineChains(
|
void T_OptData::buildUseDefineChains(
|
||||||
T_OpsParserOutput& program ) noexcept
|
T_OpsParserOutput& program ) noexcept
|
||||||
{
|
{
|
||||||
|
@ -386,70 +459,10 @@ void T_OptData::buildUseDefineChains(
|
||||||
* looking at the call sites.
|
* looking at the call sites.
|
||||||
*/
|
*/
|
||||||
visitor.visit( program.root , [&]( auto& n , const bool exit ) {
|
visitor.visit( program.root , [&]( auto& n , const bool exit ) {
|
||||||
if ( n.type( ) != A_Node::EXPR_ID || exit ) {
|
if ( n.type( ) == A_Node::EXPR_ID && !exit ) {
|
||||||
return true;
|
BUDCAddUseRecord_( n , *this , program.root );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find instruction and function index
|
|
||||||
auto& nId{ dynamic_cast< T_IdentifierExprNode& >( n ) };
|
|
||||||
A_FuncNode* func{ nullptr };
|
|
||||||
T_Optional< uint32_t > instrId;
|
|
||||||
A_Node* pn{ &nId };
|
|
||||||
while ( pn ) {
|
|
||||||
auto* const asInstr{ dynamic_cast< A_InstructionNode* >( pn ) };
|
|
||||||
func = dynamic_cast< A_FuncNode* >( pn );
|
|
||||||
if ( !instrId && asInstr ) {
|
|
||||||
instrId = indexOf( *asInstr );
|
|
||||||
} else if ( func ) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
pn = &pn->parent( );
|
|
||||||
}
|
|
||||||
assert( func && instrId );
|
|
||||||
|
|
||||||
// Generate the identifier
|
|
||||||
const T_VarId varId{ [&]() {
|
|
||||||
auto const& n{ nId.id( ) };
|
|
||||||
if ( func->hasLocal( nId.id( ) ) ) {
|
|
||||||
return T_VarId{ n , func->name( ) ,
|
|
||||||
func->isArgument( nId.id( ) ) };
|
|
||||||
}
|
|
||||||
return T_VarId{ n };
|
|
||||||
} () };
|
|
||||||
|
|
||||||
// Access or create the record
|
|
||||||
auto* const varRec{ [&]() {
|
|
||||||
auto* const x{ varUDChains.get( varId ) };
|
|
||||||
if ( x ) {
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
varUDChains.add( T_VarUseDefine{ varId } );
|
|
||||||
return varUDChains.get( varId );
|
|
||||||
} () };
|
|
||||||
assert( varRec );
|
|
||||||
|
|
||||||
// Add use record
|
|
||||||
auto& useRec{ varRec->uses.addNew( ) };
|
|
||||||
useRec.node = *instrId;
|
|
||||||
useRec.fnIndex = program.root.functionIndex( func->name( ) );
|
|
||||||
|
|
||||||
logger( [&](){
|
|
||||||
T_StringBuilder sb;
|
|
||||||
sb << "use " << varId.name << " at " << nId.location( ) << " (";
|
|
||||||
if ( varId.type == E_UDVarType::GLOBAL ) {
|
|
||||||
sb << "global";
|
|
||||||
} else {
|
|
||||||
if ( varId.type == E_UDVarType::LOCAL ) {
|
|
||||||
sb << "local";
|
|
||||||
} else {
|
|
||||||
sb << "argument";
|
|
||||||
}
|
|
||||||
sb << " of " << varId.owner;
|
|
||||||
}
|
|
||||||
sb << ')';
|
|
||||||
return sb;
|
|
||||||
} , LL2 );
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} );
|
} );
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue