From fa7fba0f98199cd4d5c8fc5961e01aae4cd1baf6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emmanuel=20Beno=C3=AEt?= Date: Mon, 4 Dec 2017 07:03:54 +0100 Subject: [PATCH] Optimizer - Var use finder refactored --- c-opopt.cc | 137 +++++++++++++++++++++++++++++------------------------ 1 file changed, 75 insertions(+), 62 deletions(-) diff --git a/c-opopt.cc b/c-opopt.cc index a22a831..21248a4 100644 --- a/c-opopt.cc +++ b/c-opopt.cc @@ -356,6 +356,7 @@ void T_OptData::buildControlFlowGraph( /*= T_OptData - USE/DEFINE CHAINS ============================================*/ +namespace { #warning Remove this later #undef LL1 @@ -363,6 +364,78 @@ void T_OptData::buildControlFlowGraph( #define LL1 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 + +/*----------------------------------------------------------------------------*/ + void T_OptData::buildUseDefineChains( T_OpsParserOutput& program ) noexcept { @@ -386,70 +459,10 @@ void T_OptData::buildUseDefineChains( * looking at the call sites. */ visitor.visit( program.root , [&]( auto& n , const bool exit ) { - if ( n.type( ) != A_Node::EXPR_ID || exit ) { - return true; + if ( n.type( ) == A_Node::EXPR_ID && !exit ) { + 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; } ); }