#ifndef GOOSE_LLR_BRANCH_H
#define GOOSE_LLR_BRANCH_H

namespace goose::llr
{
    class BasicBlock;

    class Branch
    {
        public:
            template< typename B >
            Branch( B&& dest ) :
                m_dest( forward< B >( dest ) )
            {}

            const auto& dest() const { return m_dest; }

            bool canBeExecuted() const { return true; }
            bool canBeEagerlyEvaluated() const { return true; }

            void setupBackLinks( uint32_t srcBBIndex );

        private:
            wptr< BasicBlock > m_dest;
    };

    class CondBranch
    {
        public:
            template< typename V, typename BT, typename BF >
            CondBranch( V&& cond, BT&& trueDest, BF&& falseDest ) :
                m_cond( forward< V >( cond ) ),
                m_trueDest( forward< BT >( trueDest ) ),
                m_falseDest( forward< BF >( falseDest ) )
            {}

            const auto& cond() const { return m_cond; }
            const auto& trueDest() const { return m_trueDest; }
            const auto& falseDest() const { return m_falseDest; }

            bool canBeExecuted() const
            {
                return IsValueConstantOrExecutable( m_cond );
            }

            bool canBeEagerlyEvaluated() const
            {
                return CanValueBeEagerlyEvaluated( m_cond );
            }

            void setupBackLinks( uint32_t srcBBIndex );

        private:
            ir::Value m_cond;
            wptr< BasicBlock > m_trueDest;
            wptr< BasicBlock > m_falseDest;
    };
}

#endif
