Artifact 2dc9c399a718a84d8defd8bf3f6452dbe26808317137d71165480744f63866f3:
- File
bs/llr/cfg.h
— part of check-in
[7a7e54ac04]
at
2020-07-18 16:25:47
on branch llr-stack-language
— Computed values now carry lists of instructions around, instead of expression trees. Also absolutely nothing works anymore.
Update: closing this branch as I will finally not pursue this. (user: achavasse size: 4279)
#ifndef GOOSE_LLR_CFG_H #define GOOSE_LLR_CFG_H namespace goose::llr { class BasicBlock; class CFG : public enable_shared_from_this< CFG > { public: CFG( uint32_t numParams ) : m_temporariesCount( numParams ) {} 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; } uint32_t loopCount() const { return m_loopCount; } void incLoopCount() { ++m_loopCount; } // If the BB of index 1 dominates the BB of index 2, returns the distance: // 0 if BB1 and BB2 are the same, 1 if BB1 is the immediate dominator, 2 if it is // the dominator's dominator, and so on. // Note: dominators needs to have been computed for the CFG before hand by // calling ComputeDominators(). optional< uint32_t > getDominatorDistance( uint32_t bbIndex1, uint32_t bbIndex2 ) const; const auto& getBB( uint32_t index ) const { return m_basicBlocks[index - 1]; } auto count() const { return m_basicBlocks.size(); } 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 ); } void setAddressModifiedByLoop( uint32_t loopId, const ir::Term& type, const Address& addr ) { m_loopModifiedAddresses.emplace( make_pair( loopId, addr ), type ); } template< typename F > void forEachAddressModifiedInLoop( uint32_t loopId, F&& func ) const { auto begin = m_loopModifiedAddresses.lower_bound( { loopId, 0U } ); auto end = m_loopModifiedAddresses.upper_bound( { loopId, ~0U } ); for( auto it = begin; it != end; ++it ) func( it->second, it->first.second ); } 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. // May be be empty if it has not (yet) been computed. vector< uint32_t > m_idoms; // For each loop, store all of the adresses modified // during that loop. // May be be empty if it has not (yet) been computed. multimap< pair< uint32_t, Address >, ir::Term > m_loopModifiedAddresses; // The number of temporary indices used by this CFG. uint32_t m_temporariesCount = 0; uint32_t m_loopCount = 0; bool m_poisoned = false; }; // Compute the immediate dominators for each BB in the provided CFG, // using the Lengauer-Tarjan algorithm. extern void ComputeDominators( const ptr< CFG >& cfg ); // Detect loops and store loop informations into the CFG. extern void ComputeLoops( const ptr< CFG >& cfg ); // Find which loop modifies which variable. extern void ComputeLoopModifiedAddrs( const ptr< CFG >& cfg ); } #endif