#ifndef GOOSE_LLR_CFG_H
#define GOOSE_LLR_CFG_H
namespace goose::llr
{
class BasicBlock;
class CFG : public enable_shared_from_this< CFG >
{
public:
bool isPoisoned() const { return m_poisoned; }
void poison() { m_poisoned = true; }
const auto& entryBB() const { return m_basicBlocks.front(); }
const auto& lastBB() const { return m_basicBlocks.back(); }
const auto& currentBB() const { return m_currentBB; }
template< typename T >
void setCurrentBB( T&& pBB )
{
m_currentBB = forward< T >( pBB );
}
void addEdge( uint32_t srcIndex, uint32_t destIndex );
const auto& edges() const { return m_edges; }
template< typename V >
void setIdoms( V&& idoms )
{
m_idoms = forward< V >( idoms );
}
const auto& idoms() const { return m_idoms; }
const auto& getBB( uint32_t index ) { return m_basicBlocks[index - 1]; }
auto count() const { return m_basicBlocks.size(); }
auto uniqueId() const { return m_uniqueId; }
const ptr< llr::BasicBlock >& createBB();
auto getNewTemporaryIndex() { return m_temporariesCount++; }
// Clear the llvm basic block pointers from the entire cfg.
void unbindFromLLVM();
bool canBeExecuted() const;
bool canBeEagerlyEvaluated() const;
template< typename F >
void ForEachBB( F&& func )
{
for( auto&& bb : m_basicBlocks )
func( bb );
}
private:
vector< ptr< BasicBlock > > m_basicBlocks;
ptr< BasicBlock > m_currentBB;
// All the edges of the CFG in SrcBBIndex, DestBBIndex form
unordered_multimap< uint32_t, uint32_t > m_edges;
// For each BB, store the index of its immediate dominator.
// Maybe be empty if it has not (yet) been computed.
vector< uint32_t > m_idoms;
// The unique identifier of this CFG.
uint32_t m_uniqueId = ms_nextUniqueId++;
// The number of temporary indices used by this CFG.
uint32_t m_temporariesCount = 0;
bool m_poisoned = false;
static uint32_t ms_nextUniqueId;
};
}
#endif