From fac8de1fde1dac1f78a7f2e22c536a9781f9a246 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emmanuel=20Beno=C3=AEt?= Date: Fri, 8 Dec 2017 22:00:43 +0100 Subject: [PATCH] Optimizer - Mostly OK use/define chain construction In which "mostly" means that it will work, unless: 1/ something is used before being defined (will trigger assertion) 2/ a local variable is re-used before being redefined, which will be detected as using the def from the previous execution (won't be a problem for now as it'll crash first, due to (1)) --- c-opopt.cc | 41 ++++++++++++++++++++++++++++++++--------- 1 file changed, 32 insertions(+), 9 deletions(-) diff --git a/c-opopt.cc b/c-opopt.cc index a0dd4c4..49c706c 100644 --- a/c-opopt.cc +++ b/c-opopt.cc @@ -692,6 +692,7 @@ void T_OptData::buildUseDefineChains( auto& resource{ varUDChains[ rec.entry ] }; const auto defId{ (*activeDefs)[ rec.entry ] }; // FIXME: must be defined + assert( defId != T_HashIndex::INVALID_INDEX ); resource.defines[ defId ].refs.add( rec.index ); resource.uses[ rec.index ].refs.add( defId ); logger( [&](){ @@ -712,7 +713,7 @@ void T_OptData::buildUseDefineChains( (*activeDefs)[ rec.entry ] = rec.index; logger( [&](){ T_StringBuilder sb; - sb << "DEF " << rec.index + sb << "DEF " << rec.index << ' ' << varUDChains[ rec.entry ].var.name << " @ instr #" << ii; return sb; @@ -726,10 +727,6 @@ void T_OptData::buildUseDefineChains( } // Check for possible next nodes - // -> no output nodes left -> pop stack and keep trying, - // unless we've already processed all nodes - // -> if there's only one, use it and don't push to stack - // -> otherwise push to stack, use first available node do { auto const& rcn{ *ctrlFlowGraph[ node ] }; const uint32_t nSuccs{ [&](){ @@ -742,23 +739,49 @@ void T_OptData::buildUseDefineChains( } return c; }() }; - logger( [=]() { + logger( [&]() { T_StringBuilder sb; sb << "node " << node << ": " << nSuccs - << " successor(s) left"; + << " successor(s) left (stack depth " + << stack.size( ) << ')'; return sb; } , LL2 ); + // -> no output nodes left -> pop stack and keep trying, + // unless we've already processed all nodes if ( nSuccs == 0 ) { assert( !stack.empty( ) ); node = stack.last( ).node; activeDefs = std::move( stack.last( ).def ); stack.removeLast( ); + logger( [&]() { + T_StringBuilder sb; + sb << "pop stack -> next node " << node + << " (stack depth " + << stack.size( ) << ')'; + return sb; + } , LL2 ); continue; } - // TODO cases in which there is one or more successors - } while ( 0 ); // XXX + const auto no{ rcn.outbound.size( ) }; + uint32_t nn{ T_HashIndex::INVALID_INDEX }; + for ( auto i = 0u ; i < no ; i ++ ) { + if ( !processedNodes[ rcn.outbound[ i ] ] ) { + nn = rcn.outbound[ i ]; + break; + } + } + + // More than one possible successor? Push to stack + if ( nSuccs > 1 ) { + M_LOGSTR_( "pushing node" , LL2 ); + stack.addNew( activeDefs , node ); + } + + node = nn; + break; + } while ( 1 ); // 30 if next block is an end of function, kill locals }