#ifndef GOOSE_CIR_HELPERS_H #define GOOSE_CIR_HELPERS_H namespace goose::cir { class Instruction; using InstrSeq = list< Instruction >; extern bool IsValueConstantOrExecutable( const eir::Value& val ); extern bool CanValueBeEagerlyEvaluated( const eir::Value& val ); extern void AppendInstrSeq( InstrSeq& is, InstrSeq&& isToAppend ); extern void AppendInstrSeq( InstrSeq& is, const InstrSeq& isToAppend ); extern void AppendValue( InstrSeq& is, Value&& v ); extern void AppendValue( InstrSeq& is, const Value& v ); template< typename I > void AppendToInstrSeq( InstrSeq& is, I&& instr ) { using II = remove_cvref_t< I >; if constexpr( is_same_v< II, InstrSeq > ) { AppendInstrSeq( is, forward< I >( instr ) ); } else if constexpr( is_same_v< II, Value > ) { AppendValue( is, forward< I >( instr ) ); } else { is.emplace_back( Instruction( forward< I >( instr ) ) ); } } static inline void AppendToInstrSeq( InstrSeq& is, const ptr< InstrSeq >& instr ) { AppendToInstrSeq( is, *instr ); } static inline void AppendToInstrSeq( InstrSeq& is, ptr< InstrSeq >&& instr ) { AppendToInstrSeq( is, move( *instr ) ); } template< typename HI, typename... TI > void AppendToInstrSeq( InstrSeq& is, HI&& headInstr, TI&&... tailInstrs ) { AppendToInstrSeq( is, forward< HI >( headInstr ) ); AppendToInstrSeq( is, forward< TI >( tailInstrs )... ); } template< typename T, typename... I > auto BuildComputedValue( T&& type, I&&... instrs ) { auto is = make_shared< InstrSeq >(); AppendToInstrSeq( *is, forward< I >( instrs )... ); return eir::Value( forward< T >( type ), move( is ) ); } template< typename T > class TempStorage { public: template< typename TT > auto& set( uint32_t index, TT&& x ) { auto [it, inserted] = m_storage.try_emplace( index ); it->second = forward< TT >( x ); return it->second; } const T* get( uint32_t index ) const { auto it = m_storage.find( index ); if( it == m_storage.end() ) return nullptr; return &it->second; } T* get( uint32_t index ) { auto it = m_storage.find( index ); if( it == m_storage.end() ) return nullptr; return &it->second; } private: unordered_map< uint32_t, T > m_storage; }; } #endif