#ifndef GOOSE_CIR_INSTRUCTION_H
#define GOOSE_CIR_INSTRUCTION_H
namespace goose::cir
{
class CFG;
class Instruction
{
public:
Instruction() {}
Instruction( Call&& c ) :
m_content( move( c ) )
{}
Instruction( VarAddr&& vad ) :
m_content( move( vad ) )
{}
Instruction( TempAddr&& tad ) :
m_content( move( tad ) )
{}
Instruction( Select&& sel ) :
m_content( move( sel ) )
{}
Instruction( Constant&& cst ) :
m_content( move( cst ) )
{}
Instruction( CreateTemporary&& ct ) :
m_content( move( ct ) )
{}
Instruction( GetTemporary&& gt ) :
m_content( move( gt ) )
{}
Instruction( AllocVar&& av ) :
m_content( move( av ) )
{}
Instruction( Load&& l ) :
m_content( move( l ) )
{}
Instruction( Store&& s ) :
m_content( move( s ) )
{}
Instruction( Phi&& p ) :
m_content( move( p ) )
{}
Instruction( Not&& x ) :
m_content( move( x ) )
{}
Instruction( And&& x ) :
m_content( move( x ) )
{}
Instruction( Or&& x ) :
m_content( move( x ) )
{}
Instruction( Xor&& x ) :
m_content( move( x ) )
{}
Instruction( Implies&& x ) :
m_content( move( x ) )
{}
Instruction( Shl&& x ) :
m_content( move( x ) )
{}
Instruction( LShr&& x ) :
m_content( move( x ) )
{}
Instruction( AShr&& x ) :
m_content( move( x ) )
{}
Instruction( Add&& x ) :
m_content( move( x ) )
{}
Instruction( Sub&& x ) :
m_content( move( x ) )
{}
Instruction( Mul&& x ) :
m_content( move( x ) )
{}
Instruction( UDiv&& x ) :
m_content( move( x ) )
{}
Instruction( SDiv&& x ) :
m_content( move( x ) )
{}
Instruction( URem&& x ) :
m_content( move( x ) )
{}
Instruction( SRem&& x ) :
m_content( move( x ) )
{}
Instruction( Eq&& x ) :
m_content( move( x ) )
{}
Instruction( Neq&& x ) :
m_content( move( x ) )
{}
Instruction( UGT&& x ) :
m_content( move( x ) )
{}
Instruction( UGE&& x ) :
m_content( move( x ) )
{}
Instruction( ULT&& x ) :
m_content( move( x ) )
{}
Instruction( ULE&& x ) :
m_content( move( x ) )
{}
Instruction( SGT&& x ) :
m_content( move( x ) )
{}
Instruction( SGE&& x ) :
m_content( move( x ) )
{}
Instruction( SLT&& x ) :
m_content( move( x ) )
{}
Instruction( SLE&& x ) :
m_content( move( x ) )
{}
Instruction( Assert&& x ) :
m_content( move( x ) )
{}
Instruction( Placeholder&& x ) :
m_content( move( x ) )
{}
Instruction( PHOverrideSet&& x ) :
m_content( move( x ) )
{}
Instruction( PHOverrideClear&& x ) :
m_content( move( x ) )
{}
Instruction( GhostCall&& x ) :
m_content( move( x ) )
{}
Instruction( IsPrefixOf&& x ) :
m_content( move( x ) )
{}
using Content = variant
<
monostate,
Call,
VarAddr,
TempAddr,
Select,
Constant,
CreateTemporary,
GetTemporary,
AllocVar,
Load,
Store,
Phi,
Not,
And,
Or,
Xor,
Implies,
IsPrefixOf,
Shl,
LShr,
AShr,
Add,
Sub,
Mul,
UDiv,
SDiv,
URem,
SRem,
Eq,
Neq,
UGT,
UGE,
ULT,
ULE,
SGT,
SGE,
SLT,
SLE,
Assert,
GhostCall,
PHOverrideSet,
PHOverrideClear,
Placeholder
>;
const auto& content() const { return m_content; }
auto& content() { return m_content; }
bool canBeExecuted() const;
bool canBeEagerlyEvaluated() const;
bool haveSideEffects() const;
friend ostream& operator<<( ostream& out, const Instruction& inst );
bool operator<( const Instruction& rhs ) const
{
return m_content < rhs.m_content;
}
private:
Content m_content;
};
}
#endif