Optimizer - Call bypass edges in CFG

It will make things simpler when walking the graph for locals.
This commit is contained in:
Emmanuel BENOîT 2017-12-10 11:57:07 +01:00
parent b2c11d8d2a
commit f37c0d0df3
2 changed files with 16 additions and 6 deletions

View file

@ -32,10 +32,19 @@ T_StringBuilder& opopt::operator<<(
T_OptData::T_CtrlFlowEdge const& value ) noexcept T_OptData::T_CtrlFlowEdge const& value ) noexcept
{ {
obj << value.target; obj << value.target;
if ( value.type == T_OptData::T_CtrlFlowEdge::CALL ) { switch ( value.type ) {
case T_OptData::T_CtrlFlowEdge::CALL:
obj << "{c}"; obj << "{c}";
} else if ( value.type == T_OptData::T_CtrlFlowEdge::RET ) { break;
case T_OptData::T_CtrlFlowEdge::RET:
obj << "{r}"; obj << "{r}";
break;
case T_OptData::T_CtrlFlowEdge::BYPASS:
obj << "{b}";
break;
case T_OptData::T_CtrlFlowEdge::FLOW:
break;
} }
return obj; return obj;
} }
@ -401,6 +410,7 @@ inline void BCFGHandleCalls_(
// Handle calls // Handle calls
constexpr auto tCall{ T_OptData::T_CtrlFlowEdge::CALL }; constexpr auto tCall{ T_OptData::T_CtrlFlowEdge::CALL };
constexpr auto tRet{ T_OptData::T_CtrlFlowEdge::RET }; constexpr auto tRet{ T_OptData::T_CtrlFlowEdge::RET };
constexpr auto tBypass{ T_OptData::T_CtrlFlowEdge::BYPASS };
for ( auto const& cs : data.callSites ) { for ( auto const& cs : data.callSites ) {
auto const* frec{ data.cfgFunctions.get( cs.name ) }; auto const* frec{ data.cfgFunctions.get( cs.name ) };
assert( frec ); assert( frec );
@ -420,9 +430,9 @@ inline void BCFGHandleCalls_(
bExit.outbound.addNew( cs.retBlock , tRet ); bExit.outbound.addNew( cs.retBlock , tRet );
bRet.inbound.addNew( nExit , tRet ); bRet.inbound.addNew( nExit , tRet );
// Normal flow, skipping the call // Call bypass
bCall.outbound.addNew( cs.retBlock ); bCall.outbound.addNew( cs.retBlock , tBypass );
bRet.inbound.addNew( cs.callBlock ); bRet.inbound.addNew( cs.callBlock , tBypass );
} }
} }

View file

@ -70,7 +70,7 @@ struct T_OptData
struct T_CtrlFlowEdge struct T_CtrlFlowEdge
{ {
enum E_Type { enum E_Type {
FLOW , CALL , RET FLOW , CALL , RET , BYPASS
}; };
uint32_t target; uint32_t target;