Optimizer - Call bypass edges in CFG
It will make things simpler when walking the graph for locals.
This commit is contained in:
parent
b2c11d8d2a
commit
f37c0d0df3
2 changed files with 16 additions and 6 deletions
20
c-opopt.cc
20
c-opopt.cc
|
@ -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 );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -70,7 +70,7 @@ struct T_OptData
|
|||
struct T_CtrlFlowEdge
|
||||
{
|
||||
enum E_Type {
|
||||
FLOW , CALL , RET
|
||||
FLOW , CALL , RET , BYPASS
|
||||
};
|
||||
|
||||
uint32_t target;
|
||||
|
|
Loading…
Reference in a new issue