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

View file

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