Optimizer - Edge types in CFG
Control flow graph edges have been assigned a type, which may be either FLOW (for normal edges), CALL (for edges that enter a function) or RET (for edges that exit a function). In addition, call sites have an additional FLOW edge that bypasses the function call.
This commit is contained in:
parent
ddad981055
commit
cb42137592
2 changed files with 53 additions and 15 deletions
46
c-opopt.cc
46
c-opopt.cc
|
@ -27,6 +27,19 @@ uint32_t opopt::ComputeHash(
|
||||||
^ ( ( oh << 29 ) | ( oh >> 3 ) );
|
^ ( ( oh << 29 ) | ( oh >> 3 ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
T_StringBuilder& opopt::operator<<(
|
||||||
|
T_StringBuilder& obj ,
|
||||||
|
T_OptData::T_CtrlFlowEdge const& value ) noexcept
|
||||||
|
{
|
||||||
|
obj << value.target;
|
||||||
|
if ( value.type == T_OptData::T_CtrlFlowEdge::CALL ) {
|
||||||
|
obj << "{c}";
|
||||||
|
} else if ( value.type == T_OptData::T_CtrlFlowEdge::RET ) {
|
||||||
|
obj << "{r}";
|
||||||
|
}
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
constexpr uint32_t T_OptData::CFG_ENTER;
|
constexpr uint32_t T_OptData::CFG_ENTER;
|
||||||
constexpr uint32_t T_OptData::CFG_MAINLOOP;
|
constexpr uint32_t T_OptData::CFG_MAINLOOP;
|
||||||
constexpr uint32_t T_OptData::CFG_END;
|
constexpr uint32_t T_OptData::CFG_END;
|
||||||
|
@ -386,21 +399,30 @@ inline void BCFGHandleCalls_(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle calls
|
// Handle calls
|
||||||
|
constexpr auto tCall{ T_OptData::T_CtrlFlowEdge::CALL };
|
||||||
|
constexpr auto tRet{ T_OptData::T_CtrlFlowEdge::RET };
|
||||||
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 );
|
||||||
{
|
|
||||||
auto& entry{ data.ctrlFlowGraph[ frec->first ] };
|
|
||||||
entry->inbound.add( cs.callBlock );
|
const auto nExit{ frec->first + frec->count - 1 };
|
||||||
data.ctrlFlowGraph[ cs.callBlock ]->outbound.add(
|
auto& bCall{ *data.ctrlFlowGraph[ cs.callBlock ] };
|
||||||
frec->first );
|
auto& bRet{ *data.ctrlFlowGraph[ cs.retBlock ] };
|
||||||
}
|
auto& bEntry{ *data.ctrlFlowGraph[ frec->first ] };
|
||||||
{
|
auto& bExit{ *data.ctrlFlowGraph[ nExit ] };
|
||||||
const auto n{ frec->first + frec->count - 1 };
|
|
||||||
auto& exit{ data.ctrlFlowGraph[ n ] };
|
// Call
|
||||||
exit->outbound.add( cs.retBlock );
|
bEntry.inbound.addNew( cs.callBlock , tCall );
|
||||||
data.ctrlFlowGraph[ cs.retBlock ]->inbound.add( n );
|
bCall.outbound.addNew( frec->first , tCall );
|
||||||
}
|
|
||||||
|
// Return
|
||||||
|
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 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
22
c-opopt.hh
22
c-opopt.hh
|
@ -66,12 +66,27 @@ struct T_OptData
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
|
|
||||||
// Control flow graph node
|
// Control flow graph edges and nodes
|
||||||
|
struct T_CtrlFlowEdge
|
||||||
|
{
|
||||||
|
enum E_Type {
|
||||||
|
FLOW , CALL , RET
|
||||||
|
};
|
||||||
|
|
||||||
|
uint32_t target;
|
||||||
|
E_Type type;
|
||||||
|
|
||||||
|
T_CtrlFlowEdge(
|
||||||
|
const uint32_t target ,
|
||||||
|
const E_Type type = FLOW ) noexcept
|
||||||
|
: target{ target } , type{ type }
|
||||||
|
{}
|
||||||
|
};
|
||||||
struct T_CtrlFlowNode
|
struct T_CtrlFlowNode
|
||||||
{
|
{
|
||||||
T_Optional< T_BasicBlock > instructions;
|
T_Optional< T_BasicBlock > instructions;
|
||||||
T_AutoArray< uint32_t , 16 > inbound;
|
T_AutoArray< T_CtrlFlowEdge , 16 > inbound;
|
||||||
T_AutoArray< uint32_t , 16 > outbound;
|
T_AutoArray< T_CtrlFlowEdge , 16 > outbound;
|
||||||
};
|
};
|
||||||
using P_CtrlFlowNode = T_OwnPtr< T_CtrlFlowNode >;
|
using P_CtrlFlowNode = T_OwnPtr< T_CtrlFlowNode >;
|
||||||
|
|
||||||
|
@ -171,6 +186,7 @@ struct T_OptData
|
||||||
};
|
};
|
||||||
|
|
||||||
uint32_t ComputeHash( T_OptData::T_VarId const& id ) noexcept;
|
uint32_t ComputeHash( T_OptData::T_VarId const& id ) noexcept;
|
||||||
|
M_LSHIFT_OP( T_StringBuilder , T_OptData::T_CtrlFlowEdge const& ) noexcept;
|
||||||
|
|
||||||
|
|
||||||
/*= INDIVIDUAL OPTIMISATIONS =================================================*/
|
/*= INDIVIDUAL OPTIMISATIONS =================================================*/
|
||||||
|
|
Loading…
Reference in a new issue