summaryrefslogtreecommitdiff
path: root/src/mir/mir_builder.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mir/mir_builder.cpp')
-rw-r--r--src/mir/mir_builder.cpp731
1 files changed, 323 insertions, 408 deletions
diff --git a/src/mir/mir_builder.cpp b/src/mir/mir_builder.cpp
index 478146e8..97942ba2 100644
--- a/src/mir/mir_builder.cpp
+++ b/src/mir/mir_builder.cpp
@@ -26,21 +26,30 @@ MirBuilder::MirBuilder(const Span& sp, const StaticTraitResolve& resolve, const
}
set_cur_block( new_bb_unlinked() );
- m_scopes.push_back( ScopeDef { sp } );
+ m_scopes.push_back( ScopeDef { sp, ScopeType::make_Owning({ false, {} }) } );
m_scope_stack.push_back( 0 );
- m_scopes.push_back( ScopeDef { sp, ScopeType::make_Temporaries({}) } );
+ m_scopes.push_back( ScopeDef { sp, ScopeType::make_Owning({ true, {} }) } );
m_scope_stack.push_back( 1 );
+ m_arg_states.reserve( args.size() );
+ for(size_t i = 0; i < args.size(); i ++)
+ m_arg_states.push_back( VarState::make_Valid({}) );
+ m_slot_states.resize( output.locals.size() );
+ m_first_temp_idx = output.locals.size();
+ DEBUG("First temporary will be " << m_first_temp_idx);
m_if_cond_lval = this->new_temporary(::HIR::CoreType::Bool);
- m_arg_states.reserve( args.size() );
- for(size_t i = 0; i < args.size(); i ++ )
- m_arg_states.push_back( VarState::make_Valid({}) );
- m_variable_states.reserve( output.named_variables.size() );
- for(size_t i = 0; i < output.named_variables.size(); i ++ )
- m_variable_states.push_back( VarState::make_Invalid(InvalidType::Uninit) );
+ // Determine which variables can be replaced by arguents
+ for(size_t i = 0; i < args.size(); i ++)
+ {
+ const auto& pat = args[i].first;
+ if( pat.m_binding.is_valid() && pat.m_binding.m_type == ::HIR::PatternBinding::Type::Move )
+ {
+ m_var_arg_mappings[pat.m_binding.m_slot] = i;
+ }
+ }
}
MirBuilder::~MirBuilder()
{
@@ -51,8 +60,9 @@ MirBuilder::~MirBuilder()
{
push_stmt_assign( sp, ::MIR::LValue::make_Return({}), get_result(sp) );
}
- terminate_scope( sp, ScopeHandle { *this, 1 } );
- terminate_scope( sp, mv$(m_fcn_scope) );
+
+ terminate_scope_early(sp, fcn_scope());
+
end_block( ::MIR::Terminator::make_Return({}) );
}
}
@@ -74,7 +84,7 @@ const ::HIR::TypeRef* MirBuilder::is_type_owned_box(const ::HIR::TypeRef& ty) co
if( pe.m_path != *m_lang_Box ) {
return nullptr;
}
- // TODO: Properly assert?
+ // TODO: Properly assert the size?
return &pe.m_params.m_types.at(0);
}
else
@@ -85,18 +95,21 @@ const ::HIR::TypeRef* MirBuilder::is_type_owned_box(const ::HIR::TypeRef& ty) co
void MirBuilder::define_variable(unsigned int idx)
{
- DEBUG("DEFINE var" << idx << ": " << m_output.named_variables.at(idx));
+ DEBUG("DEFINE (var) _" << idx << ": " << m_output.locals.at(idx));
for( auto scope_idx : ::reverse(m_scope_stack) )
{
auto& scope_def = m_scopes.at(scope_idx);
TU_MATCH_DEF( ScopeType, (scope_def.data), (e),
(
),
- (Variables,
- auto it = ::std::find(e.vars.begin(), e.vars.end(), idx);
- assert(it == e.vars.end());
- e.vars.push_back( idx );
- return ;
+ (Owning,
+ if( !e.is_temporary )
+ {
+ auto it = ::std::find(e.slots.begin(), e.slots.end(), idx);
+ assert(it == e.slots.end());
+ e.slots.push_back( idx );
+ return ;
+ }
),
(Split,
BUG(Span(), "Variable " << idx << " introduced within a Split");
@@ -107,20 +120,24 @@ void MirBuilder::define_variable(unsigned int idx)
}
::MIR::LValue MirBuilder::new_temporary(const ::HIR::TypeRef& ty)
{
- unsigned int rv = m_output.temporaries.size();
- DEBUG("DEFINE tmp" << rv << ": " << ty);
+ unsigned int rv = m_output.locals.size();
+ DEBUG("DEFINE (temp) _" << rv << ": " << ty);
- m_output.temporaries.push_back( ty.clone() );
- m_temporary_states.push_back( VarState::make_Invalid(InvalidType::Uninit) );
- assert(m_output.temporaries.size() == m_temporary_states.size());
+ assert(m_output.locals.size() == m_slot_states.size());
+ m_output.locals.push_back( ty.clone() );
+ m_slot_states.push_back( VarState::make_Invalid(InvalidType::Uninit) );
+ assert(m_output.locals.size() == m_slot_states.size());
ScopeDef* top_scope = nullptr;
for(unsigned int i = m_scope_stack.size(); i --; )
{
auto idx = m_scope_stack[i];
- if( m_scopes.at( idx ).data.is_Temporaries() ) {
- top_scope = &m_scopes.at(idx);
- break ;
+ if( const auto* e = m_scopes.at( idx ).data.opt_Owning() ) {
+ if( e->is_temporary )
+ {
+ top_scope = &m_scopes.at(idx);
+ break ;
+ }
}
else if( m_scopes.at(idx).data.is_Loop() )
{
@@ -140,9 +157,10 @@ void MirBuilder::define_variable(unsigned int idx)
}
}
assert( top_scope );
- auto& tmp_scope = top_scope->data.as_Temporaries();
- tmp_scope.temporaries.push_back( rv );
- return ::MIR::LValue::make_Temporary({rv});
+ auto& tmp_scope = top_scope->data.as_Owning();
+ assert(tmp_scope.is_temporary);
+ tmp_scope.slots.push_back( rv );
+ return ::MIR::LValue::make_Local(rv);
}
::MIR::LValue MirBuilder::lvalue_or_temp(const Span& sp, const ::HIR::TypeRef& ty, ::MIR::RValue val)
{
@@ -151,7 +169,7 @@ void MirBuilder::define_variable(unsigned int idx)
)
else {
auto temp = new_temporary(ty);
- push_stmt_assign( sp, ::MIR::LValue(temp.as_Temporary()), mv$(val) );
+ push_stmt_assign( sp, temp.clone(), mv$(val) );
return temp;
}
}
@@ -320,12 +338,6 @@ void MirBuilder::push_stmt_drop(const Span& sp, ::MIR::LValue val, unsigned int
}
this->push_stmt(sp, ::MIR::Statement::make_Drop({ ::MIR::eDropKind::DEEP, mv$(val), flag }));
-
- if( flag != ~0u )
- {
- // Reset flag value back to default.
- push_stmt_set_dropflag_val(sp, flag, m_output.drop_flags.at(flag));
- }
}
void MirBuilder::push_stmt_drop_shallow(const Span& sp, ::MIR::LValue val, unsigned int flag/*=~0u*/)
{
@@ -335,12 +347,6 @@ void MirBuilder::push_stmt_drop_shallow(const Span& sp, ::MIR::LValue val, unsig
// TODO: Ensure that the type is a Box?
this->push_stmt(sp, ::MIR::Statement::make_Drop({ ::MIR::eDropKind::SHALLOW, mv$(val), flag }));
-
- if( flag != ~0u )
- {
- // Reset flag value back to default.
- push_stmt_set_dropflag_val(sp, flag, m_output.drop_flags.at(flag));
- }
}
void MirBuilder::push_stmt_asm(const Span& sp, ::MIR::Statement::Data_Asm data)
{
@@ -355,7 +361,7 @@ void MirBuilder::push_stmt_asm(const Span& sp, ::MIR::Statement::Data_Asm data)
}
void MirBuilder::push_stmt_set_dropflag_val(const Span& sp, unsigned int idx, bool value)
{
- this->push_stmt(sp, ::MIR::Statement::make_SetDropFlag({ idx, value }));
+ this->push_stmt(sp, ::MIR::Statement::make_SetDropFlag({ idx, value, ~0u }));
}
void MirBuilder::push_stmt_set_dropflag_other(const Span& sp, unsigned int idx, unsigned int other)
{
@@ -363,7 +369,7 @@ void MirBuilder::push_stmt_set_dropflag_other(const Span& sp, unsigned int idx,
}
void MirBuilder::push_stmt_set_dropflag_default(const Span& sp, unsigned int idx)
{
- this->push_stmt(sp, ::MIR::Statement::make_SetDropFlag({ idx, this->get_drop_flag_default(sp, idx) }));
+ this->push_stmt(sp, ::MIR::Statement::make_SetDropFlag({ idx, this->get_drop_flag_default(sp, idx), ~0u }));
}
void MirBuilder::push_stmt(const Span& sp, ::MIR::Statement stmt)
{
@@ -378,26 +384,15 @@ void MirBuilder::mark_value_assigned(const Span& sp, const ::MIR::LValue& dst)
TU_MATCH_DEF(::MIR::LValue, (dst), (e),
(
),
- (Temporary,
- state_p = &get_temp_state_mut(sp, e.idx);
- if( const auto* se = state_p->opt_Invalid() )
- {
- if( *se != InvalidType::Uninit ) {
- BUG(sp, "Reassigning temporary " << e.idx << " - " << *state_p);
- }
- }
- else {
- // TODO: This should be a bug, but some of the match code ends up reassigning so..
- //BUG(sp, "Reassigning temporary " << e.idx << " - " << *state_p);
- }
- ),
(Return,
// Don't drop.
// No state tracking for the return value
),
- (Variable,
- // TODO: Ensure that slot is mutable (information is lost, assume true)
- state_p = &get_variable_state_mut(sp, e);
+ (Argument,
+ state_p = &get_slot_state_mut(sp, e.idx, SlotType::Argument);
+ ),
+ (Local,
+ state_p = &get_slot_state_mut(sp, e, SlotType::Local);
)
)
@@ -411,7 +406,7 @@ void MirBuilder::mark_value_assigned(const Span& sp, const ::MIR::LValue& dst)
}
}
-void MirBuilder::raise_variables(const Span& sp, const ::MIR::LValue& val, const ScopeHandle& scope, bool to_above/*=false*/)
+void MirBuilder::raise_temporaries(const Span& sp, const ::MIR::LValue& val, const ScopeHandle& scope, bool to_above/*=false*/)
{
TRACE_FUNCTION_F(val);
TU_MATCH_DEF(::MIR::LValue, (val), (e),
@@ -422,29 +417,34 @@ void MirBuilder::raise_variables(const Span& sp, const ::MIR::LValue& val, const
// TODO: This may not be correct, because it can change the drop points and ordering
// HACK: Working around cases where values are dropped while the result is not yet used.
(Index,
- raise_variables(sp, *e.val, scope, to_above);
- raise_variables(sp, *e.idx, scope, to_above);
+ raise_temporaries(sp, *e.val, scope, to_above);
+ raise_temporaries(sp, *e.idx, scope, to_above);
return ;
),
(Deref,
- raise_variables(sp, *e.val, scope, to_above);
+ raise_temporaries(sp, *e.val, scope, to_above);
return ;
),
(Field,
- raise_variables(sp, *e.val, scope, to_above);
+ raise_temporaries(sp, *e.val, scope, to_above);
return ;
),
(Downcast,
- raise_variables(sp, *e.val, scope, to_above);
+ raise_temporaries(sp, *e.val, scope, to_above);
return ;
),
// Actual value types
- (Variable,
- ),
- (Temporary,
+ (Local,
)
)
- ASSERT_BUG(sp, val.is_Variable() || val.is_Temporary(), "Hit value raising code with non-variable value - " << val);
+ ASSERT_BUG(sp, val.is_Local(), "Hit value raising code with non-variable value - " << val);
+ const auto idx = val.as_Local();
+ bool is_temp = (idx >= m_first_temp_idx);
+ /*
+ if( !is_temp ) {
+ return ;
+ }
+ */
// Find controlling scope
auto scope_it = m_scope_stack.rbegin();
@@ -457,30 +457,20 @@ void MirBuilder::raise_variables(const Span& sp, const ::MIR::LValue& val, const
DEBUG(val << " defined in or above target (scope " << scope << ")");
}
- TU_IFLET( ScopeType, scope_def.data, Variables, e,
- if( const auto* ve = val.opt_Variable() )
+ TU_IFLET( ScopeType, scope_def.data, Owning, e,
+ if( e.is_temporary == is_temp )
{
- auto idx = *ve;
- auto tmp_it = ::std::find( e.vars.begin(), e.vars.end(), idx );
- if( tmp_it != e.vars.end() )
+ auto tmp_it = ::std::find(e.slots.begin(), e.slots.end(), idx);
+ if( tmp_it != e.slots.end() )
{
- e.vars.erase( tmp_it );
- DEBUG("Raise variable " << idx << " from " << *scope_it);
+ e.slots.erase( tmp_it );
+ DEBUG("Raise slot " << idx << " from " << *scope_it);
break ;
}
}
- )
- else TU_IFLET( ScopeType, scope_def.data, Temporaries, e,
- if( const auto* ve = val.opt_Temporary() )
+ else
{
- auto idx = ve->idx;
- auto tmp_it = ::std::find( e.temporaries.begin(), e.temporaries.end(), idx );
- if( tmp_it != e.temporaries.end() )
- {
- e.temporaries.erase( tmp_it );
- DEBUG("Raise temporary " << idx << " from " << *scope_it);
- break ;
- }
+ // TODO: Should this care about variables?
}
)
else
@@ -536,26 +526,12 @@ void MirBuilder::raise_variables(const Span& sp, const ::MIR::LValue& val, const
target_seen = true;
}
- TU_IFLET( ScopeType, scope_def.data, Variables, e,
- if( target_seen )
+ TU_IFLET( ScopeType, scope_def.data, Owning, e,
+ if( target_seen && e.is_temporary == is_temp )
{
- if( const auto* ve = val.opt_Variable() )
- {
- e.vars.push_back( *ve );
- DEBUG("- to " << *scope_it);
- return ;
- }
- }
- )
- else TU_IFLET( ScopeType, scope_def.data, Temporaries, e,
- if( target_seen )
- {
- if( const auto* ve = val.opt_Temporary() )
- {
- e.temporaries.push_back( ve->idx );
- DEBUG("- to " << *scope_it);
- return ;
- }
+ e.slots.push_back( idx );
+ DEBUG("- to " << *scope_it);
+ return ;
}
)
else if( auto* sd_loop = scope_def.data.opt_Loop() )
@@ -566,19 +542,8 @@ void MirBuilder::raise_variables(const Span& sp, const ::MIR::LValue& val, const
if( sd_loop->exit_state_valid )
{
DEBUG("Adding " << val << " as unset to loop exit state");
- if( const auto* ve = val.opt_Variable() )
- {
- auto v = sd_loop->exit_state.var_states.insert( ::std::make_pair(*ve, VarState(InvalidType::Uninit)) );
- ASSERT_BUG(sp, v.second, "Raising " << val << " which already had a state entry");
- }
- else if( const auto* ve = val.opt_Temporary() )
- {
- auto v = sd_loop->exit_state.tmp_states.insert( ::std::make_pair(ve->idx, VarState(InvalidType::Uninit)) );
- ASSERT_BUG(sp, v.second, "Raising " << val << " which already had a state entry");
- }
- else {
- BUG(sp, "Impossible raise value");
- }
+ auto v = sd_loop->exit_state.states.insert( ::std::make_pair(idx, VarState(InvalidType::Uninit)) );
+ ASSERT_BUG(sp, v.second, "Raising " << val << " which already had a state entry");
}
else
{
@@ -592,19 +557,8 @@ void MirBuilder::raise_variables(const Span& sp, const ::MIR::LValue& val, const
if( sd_split->end_state_valid )
{
DEBUG("Adding " << val << " as unset to loop exit state");
- if( const auto* ve = val.opt_Variable() )
- {
- auto v = sd_split->end_state.var_states.insert( ::std::make_pair(*ve, VarState(InvalidType::Uninit)) );
- ASSERT_BUG(sp, v.second, "Raising " << val << " which already had a state entry");
- }
- else if( const auto* ve = val.opt_Temporary() )
- {
- auto v = sd_split->end_state.tmp_states.insert( ::std::make_pair(ve->idx, VarState(InvalidType::Uninit)) );
- ASSERT_BUG(sp, v.second, "Raising " << val << " which already had a state entry");
- }
- else {
- BUG(sp, "Impossible raise value");
- }
+ auto v = sd_split->end_state.states.insert( ::std::make_pair(idx, VarState(InvalidType::Uninit)) );
+ ASSERT_BUG(sp, v.second, "Raising " << val << " which already had a state entry");
}
else
{
@@ -613,20 +567,8 @@ void MirBuilder::raise_variables(const Span& sp, const ::MIR::LValue& val, const
// TODO: This should update the outer state to unset.
auto& arm = sd_split->arms.back();
- if( const auto* ve = val.opt_Variable() )
- {
- arm.var_states.insert(::std::make_pair( *ve, get_variable_state(sp, *ve).clone() ));
- m_variable_states.at(*ve) = VarState(InvalidType::Uninit);
- }
- else if( const auto* ve = val.opt_Temporary() )
- {
- arm.tmp_states.insert(::std::make_pair( ve->idx, get_temp_state(sp, ve->idx).clone() ));
- m_temporary_states.at(ve->idx) = VarState(InvalidType::Uninit);
- }
- else
- {
- BUG(sp, "Impossible raise value");
- }
+ arm.states.insert(::std::make_pair( idx, get_slot_state(sp, idx, SlotType::Local).clone() ));
+ m_slot_states.at(idx) = VarState(InvalidType::Uninit);
}
else
{
@@ -635,15 +577,15 @@ void MirBuilder::raise_variables(const Span& sp, const ::MIR::LValue& val, const
}
BUG(sp, "Couldn't find a scope to raise " << val << " into");
}
-void MirBuilder::raise_variables(const Span& sp, const ::MIR::RValue& rval, const ScopeHandle& scope, bool to_above/*=false*/)
+void MirBuilder::raise_temporaries(const Span& sp, const ::MIR::RValue& rval, const ScopeHandle& scope, bool to_above/*=false*/)
{
auto raise_vars = [&](const ::MIR::Param& p) {
if( const auto* e = p.opt_LValue() )
- this->raise_variables(sp, *e, scope, to_above);
+ this->raise_temporaries(sp, *e, scope, to_above);
};
TU_MATCHA( (rval), (e),
(Use,
- this->raise_variables(sp, e, scope, to_above);
+ this->raise_temporaries(sp, e, scope, to_above);
),
(Constant,
),
@@ -652,23 +594,23 @@ void MirBuilder::raise_variables(const Span& sp, const ::MIR::RValue& rval, cons
),
(Borrow,
// TODO: Wait, is this valid?
- this->raise_variables(sp, e.val, scope, to_above);
+ this->raise_temporaries(sp, e.val, scope, to_above);
),
(Cast,
- this->raise_variables(sp, e.val, scope, to_above);
+ this->raise_temporaries(sp, e.val, scope, to_above);
),
(BinOp,
raise_vars(e.val_l);
raise_vars(e.val_r);
),
(UniOp,
- this->raise_variables(sp, e.val, scope, to_above);
+ this->raise_temporaries(sp, e.val, scope, to_above);
),
(DstMeta,
- this->raise_variables(sp, e.val, scope, to_above);
+ this->raise_temporaries(sp, e.val, scope, to_above);
),
(DstPtr,
- this->raise_variables(sp, e.val, scope, to_above);
+ this->raise_temporaries(sp, e.val, scope, to_above);
),
(MakeDst,
raise_vars(e.ptr_val);
@@ -743,6 +685,14 @@ unsigned int MirBuilder::new_drop_flag(bool default_state)
{
auto rv = m_output.drop_flags.size();
m_output.drop_flags.push_back(default_state);
+ for(size_t i = m_scope_stack.size(); i --;)
+ {
+ if( auto* e = m_scopes.at(m_scope_stack[i]).data.opt_Loop() )
+ {
+ e->drop_flags.push_back(rv);
+ break;
+ }
+ }
DEBUG("(" << default_state << ") = " << rv);
return rv;
}
@@ -760,7 +710,7 @@ bool MirBuilder::get_drop_flag_default(const Span& sp, unsigned int idx)
ScopeHandle MirBuilder::new_scope_var(const Span& sp)
{
unsigned int idx = m_scopes.size();
- m_scopes.push_back( ScopeDef {sp, ScopeType::make_Variables({})} );
+ m_scopes.push_back( ScopeDef {sp, ScopeType::make_Owning({ false, {} })} );
m_scope_stack.push_back( idx );
DEBUG("START (var) scope " << idx);
return ScopeHandle { *this, idx };
@@ -768,7 +718,8 @@ ScopeHandle MirBuilder::new_scope_var(const Span& sp)
ScopeHandle MirBuilder::new_scope_temp(const Span& sp)
{
unsigned int idx = m_scopes.size();
- m_scopes.push_back( ScopeDef {sp, ScopeType::make_Temporaries({})} );
+
+ m_scopes.push_back( ScopeDef {sp, ScopeType::make_Owning({ true, {} })} );
m_scope_stack.push_back( idx );
DEBUG("START (temp) scope " << idx);
return ScopeHandle { *this, idx };
@@ -786,10 +737,19 @@ ScopeHandle MirBuilder::new_scope_loop(const Span& sp)
{
unsigned int idx = m_scopes.size();
m_scopes.push_back( ScopeDef {sp, ScopeType::make_Loop({})} );
+ m_scopes.back().data.as_Loop().entry_bb = m_current_block;
m_scope_stack.push_back( idx );
DEBUG("START (loop) scope " << idx);
return ScopeHandle { *this, idx };
}
+ScopeHandle MirBuilder::new_scope_freeze(const Span& sp)
+{
+ unsigned int idx = m_scopes.size();
+ m_scopes.push_back( ScopeDef {sp, ScopeType::make_Freeze({})} );
+ m_scope_stack.push_back( idx );
+ DEBUG("START (freeze) scope " << idx);
+ return ScopeHandle { *this, idx };
+}
void MirBuilder::terminate_scope(const Span& sp, ScopeHandle scope, bool emit_cleanup/*=true*/)
{
TRACE_FUNCTION_F("DONE scope " << scope.idx << " - " << (emit_cleanup ? "CLEANUP" : "NO CLEANUP"));
@@ -852,11 +812,13 @@ void MirBuilder::raise_all(const Span& sp, ScopeHandle source, const ScopeHandle
auto& src_scope_def = m_scopes.at(source.idx);
#if 1
- ASSERT_BUG(sp, src_scope_def.data.is_Temporaries(), "Rasising scopes can only be done on temporaries (source)");
- auto& src_list = src_scope_def.data.as_Temporaries().temporaries;
+ ASSERT_BUG(sp, src_scope_def.data.is_Owning(), "Rasising scopes can only be done on temporaries (source)");
+ ASSERT_BUG(sp, src_scope_def.data.as_Owning().is_temporary, "Rasising scopes can only be done on temporaries (source)");
+ auto& src_list = src_scope_def.data.as_Owning().slots;
for(auto idx : src_list)
{
- DEBUG("> Raising " << ::MIR::LValue::make_Temporary({ idx }));
+ DEBUG("> Raising " << ::MIR::LValue::make_Local(idx));
+ assert(idx >= m_first_temp_idx);
}
// Seek up stack until the target scope is seen
@@ -873,7 +835,7 @@ void MirBuilder::raise_all(const Span& sp, ScopeHandle source, const ScopeHandle
// Insert these values as Invalid, both in the existing exit state, and in the changed list
for(auto idx : src_list)
{
- auto v = sd_loop->exit_state.tmp_states.insert(::std::make_pair( idx, VarState(InvalidType::Uninit) ));
+ auto v = sd_loop->exit_state.states.insert(::std::make_pair( idx, VarState(InvalidType::Uninit) ));
ASSERT_BUG(sp, v.second, "");
}
}
@@ -884,7 +846,7 @@ void MirBuilder::raise_all(const Span& sp, ScopeHandle source, const ScopeHandle
for(auto idx : src_list)
{
- auto v2 = sd_loop->changed_tmps.insert(::std::make_pair( idx, VarState(InvalidType::Uninit) ));
+ auto v2 = sd_loop->changed_slots.insert(::std::make_pair( idx, VarState(InvalidType::Uninit) ));
ASSERT_BUG(sp, v2.second, "");
}
}
@@ -896,7 +858,7 @@ void MirBuilder::raise_all(const Span& sp, ScopeHandle source, const ScopeHandle
// Insert these indexes as Invalid
for(auto idx : src_list)
{
- auto v = sd_split->end_state.tmp_states.insert(::std::make_pair( idx, VarState(InvalidType::Uninit) ));
+ auto v = sd_split->end_state.states.insert(::std::make_pair( idx, VarState(InvalidType::Uninit) ));
ASSERT_BUG(sp, v.second, "");
}
}
@@ -910,8 +872,8 @@ void MirBuilder::raise_all(const Span& sp, ScopeHandle source, const ScopeHandle
auto& arm = sd_split->arms.back();
for(auto idx : src_list)
{
- arm.tmp_states.insert(::std::make_pair( idx, mv$(m_temporary_states.at(idx)) ));
- m_temporary_states.at(idx) = VarState(InvalidType::Uninit);
+ arm.states.insert(::std::make_pair( idx, mv$(m_slot_states.at(idx)) ));
+ m_slot_states.at(idx) = VarState(InvalidType::Uninit);
}
}
}
@@ -920,16 +882,17 @@ void MirBuilder::raise_all(const Span& sp, ScopeHandle source, const ScopeHandle
BUG(sp, "Moving values to a scope not on the stack - scope " << target.idx);
}
auto& tgt_scope_def = m_scopes.at(target.idx);
- ASSERT_BUG(sp, tgt_scope_def.data.is_Temporaries(), "Rasising scopes can only be done on temporaries (target)");
+ ASSERT_BUG(sp, tgt_scope_def.data.is_Owning(), "Rasising scopes can only be done on temporaries (target)");
+ ASSERT_BUG(sp, tgt_scope_def.data.as_Owning().is_temporary, "Rasising scopes can only be done on temporaries (target)");
// Move all defined variables from one to the other
- auto& tgt_list = tgt_scope_def.data.as_Temporaries().temporaries;
+ auto& tgt_list = tgt_scope_def.data.as_Owning().slots;
tgt_list.insert( tgt_list.end(), src_list.begin(), src_list.end() );
#else
auto list = src_scope_def.data.as_Temporaries().temporaries;
for(auto idx : list)
{
- this->raise_variables(sp, ::MIR::LValue::make_Temporary({ idx }), target);
+ this->raise_temporaries(sp, ::MIR::LValue::make_Temporary({ idx }), target);
}
#endif
@@ -985,6 +948,18 @@ void MirBuilder::terminate_scope_early(const Span& sp, const ScopeHandle& scope,
)
}
}
+
+
+ // Index 0 is the function scope, this only happens when about to return/panic
+ if( scope.idx == 0 )
+ {
+ // Ensure that all arguments are dropped if they were not moved
+ for(size_t i = 0; i < m_arg_states.size(); i ++)
+ {
+ const auto& state = get_slot_state(sp, i, SlotType::Argument);
+ this->drop_value_from_state(sp, state, ::MIR::LValue::make_Argument({ static_cast<unsigned>(i) }));
+ }
+ }
}
namespace
@@ -1017,6 +992,9 @@ namespace
old_state = VarState::make_Optional( new_flag );
#else
// TODO: Rewrite history. I.e. visit all previous branches and set this drop flag to `false` in all of them
+ for(auto pos : other_arms) {
+ builder.push_df_set_at(pos, flag_idx, false);
+ }
TODO(sp, "Drop flag default not false when going Invalid->Optional");
#endif
}
@@ -1041,6 +1019,10 @@ namespace
builder.push_stmt_set_dropflag_other(sp, new_flag, nse.outer_flag);
builder.push_stmt_set_dropflag_default(sp, nse.outer_flag);
ose.outer_flag = new_flag;
+#if 0
+ for(auto pos : other_arms) {
+ }
+#endif
}
}
else
@@ -1388,45 +1370,39 @@ void MirBuilder::terminate_loop_early(const Span& sp, ScopeType::Data_Loop& sd_l
{
// Insert copies of parent state for newly changed values
// and Merge all changed values
- for(const auto& ent : sd_loop.changed_vars)
- {
- auto idx = ent.first;
- if( sd_loop.exit_state.var_states.count(idx) == 0 ) {
- sd_loop.exit_state.var_states.insert(::std::make_pair( idx, ent.second.clone() ));
- }
- auto& old_state = sd_loop.exit_state.var_states.at(idx);
- merge_state(sp, *this, ::MIR::LValue::make_Variable(idx), old_state, get_variable_state(sp, idx));
- }
- for(const auto& ent : sd_loop.changed_tmps)
- {
- auto idx = ent.first;
- if( sd_loop.exit_state.tmp_states.count(idx) == 0 ) {
- sd_loop.exit_state.tmp_states.insert(::std::make_pair( idx, ent.second.clone() ));
+ auto merge_list = [sp,this](const auto& changed, auto& exit_states, ::std::function<::MIR::LValue(unsigned)> val_cb, auto type) {
+ for(const auto& ent : changed)
+ {
+ auto idx = ent.first;
+ auto it = exit_states.find(idx);
+ if( it == exit_states.end() ) {
+ it = exit_states.insert(::std::make_pair( idx, ent.second.clone() )).first;
+ }
+ auto& old_state = it->second;
+ merge_state(sp, *this, val_cb(idx), old_state, get_slot_state(sp, idx, type));
}
- auto& old_state = sd_loop.exit_state.tmp_states.at(idx);
- merge_state(sp, *this, ::MIR::LValue::make_Temporary({idx}), old_state, get_temp_state(sp, idx));
- }
+ };
+ merge_list(sd_loop.changed_slots, sd_loop.exit_state.states, ::MIR::LValue::make_Local, SlotType::Local);
+ merge_list(sd_loop.changed_args, sd_loop.exit_state.arg_states, [](auto v){ return ::MIR::LValue::make_Argument({v}); }, SlotType::Argument);
}
else
{
+ auto init_list = [sp,this](const auto& changed, auto& exit_states, auto type) {
+ for(const auto& ent : changed)
+ {
+ DEBUG("Slot(" << ent.first << ") = " << ent.second);
+ auto idx = ent.first;
+ exit_states.insert(::std::make_pair( idx, get_slot_state(sp, idx, type).clone() ));
+ }
+ };
// Obtain states of changed variables/temporaries
- for(const auto& ent : sd_loop.changed_vars)
- {
- DEBUG("Variable(" << ent.first << ") = " << ent.second);
- auto idx = ent.first;
- sd_loop.exit_state.var_states.insert(::std::make_pair( idx, get_variable_state(sp, idx).clone() ));
- }
- for(const auto& ent : sd_loop.changed_tmps)
- {
- DEBUG("Temporary(" << ent.first << ") = " << ent.second);
- auto idx = ent.first;
- sd_loop.exit_state.tmp_states.insert(::std::make_pair( idx, get_temp_state(sp, idx).clone() ));
- }
+ init_list(sd_loop.changed_slots, sd_loop.exit_state.states, SlotType::Local);
+ init_list(sd_loop.changed_args, sd_loop.exit_state.arg_states, SlotType::Argument);
sd_loop.exit_state_valid = true;
}
}
-void MirBuilder::end_split_arm(const Span& sp, const ScopeHandle& handle, bool reachable)
+void MirBuilder::end_split_arm(const Span& sp, const ScopeHandle& handle, bool reachable, bool early/*=false*/)
{
ASSERT_BUG(sp, handle.idx < m_scopes.size(), "Handle passed to end_split_arm is invalid");
auto& sd = m_scopes.at( handle.idx );
@@ -1445,41 +1421,29 @@ void MirBuilder::end_split_arm(const Span& sp, const ScopeHandle& handle, bool r
{
if( reachable )
{
- // Insert copies of the parent state
- for(const auto& ent : this_arm_state.var_states) {
- if( sd_split.end_state.var_states.count(ent.first) == 0 ) {
- sd_split.end_state.var_states.insert(::std::make_pair( ent.first, get_variable_state(sp, ent.first, 1).clone() ));
- }
- }
- for(const auto& ent : this_arm_state.tmp_states) {
- if( sd_split.end_state.tmp_states.count(ent.first) == 0 ) {
- sd_split.end_state.tmp_states.insert(::std::make_pair( ent.first, get_temp_state(sp, ent.first, 1).clone() ));
+ auto merge_list = [sp,this](const auto& states, auto& end_states, auto type) {
+ // Insert copies of the parent state
+ for(const auto& ent : states) {
+ if( end_states.count(ent.first) == 0 ) {
+ end_states.insert(::std::make_pair( ent.first, get_slot_state(sp, ent.first, type, 1).clone() ));
+ }
}
- }
-
- // Merge state
- for(auto& ent : sd_split.end_state.var_states)
- {
- auto idx = ent.first;
- auto& out_state = ent.second;
-
- // Merge the states
- auto it = this_arm_state.var_states.find(idx);
- const auto& src_state = (it != this_arm_state.var_states.end() ? it->second : get_variable_state(sp, idx, 1));
-
- merge_state(sp, *this, ::MIR::LValue::make_Variable(idx), out_state, src_state);
- }
- for(auto& ent : sd_split.end_state.tmp_states)
- {
- auto idx = ent.first;
- auto& out_state = ent.second;
+ // Merge state
+ for(auto& ent : end_states)
+ {
+ auto idx = ent.first;
+ auto& out_state = ent.second;
- // Merge the states
- auto it = this_arm_state.tmp_states.find(idx);
- const auto& src_state = (it != this_arm_state.tmp_states.end() ? it->second : get_temp_state(sp, idx, 1));
+ // Merge the states
+ auto it = states.find(idx);
+ const auto& src_state = (it != states.end() ? it->second : get_slot_state(sp, idx, type, 1));
- merge_state(sp, *this, ::MIR::LValue::make_Temporary({idx}), out_state, src_state);
- }
+ auto lv = (type == SlotType::Local ? ::MIR::LValue::make_Local(idx) : ::MIR::LValue::make_Argument({idx}));
+ merge_state(sp, *this, mv$(lv), out_state, src_state);
+ }
+ };
+ merge_list(this_arm_state.states, sd_split.end_state.states, SlotType::Local);
+ merge_list(this_arm_state.arg_states, sd_split.end_state.arg_states, SlotType::Argument);
}
else
{
@@ -1489,27 +1453,34 @@ void MirBuilder::end_split_arm(const Span& sp, const ScopeHandle& handle, bool r
else
{
// Clone this arm's state
- for(auto& ent : this_arm_state.var_states)
+ for(auto& ent : this_arm_state.states)
{
- DEBUG("Variable(" << ent.first << ") = " << ent.second);
- sd_split.end_state.var_states.insert(::std::make_pair( ent.first, ent.second.clone() ));
+ DEBUG("Slot(" << ent.first << ") = " << ent.second);
+ sd_split.end_state.states.insert(::std::make_pair( ent.first, ent.second.clone() ));
}
- for(auto& ent : this_arm_state.tmp_states)
+ for(auto& ent : this_arm_state.arg_states)
{
- DEBUG("Temporary(" << ent.first << ") = " << ent.second);
- sd_split.end_state.tmp_states.insert(::std::make_pair( ent.first, ent.second.clone() ));
+ DEBUG("Argument(" << ent.first << ") = " << ent.second);
+ sd_split.end_state.arg_states.insert(::std::make_pair( ent.first, ent.second.clone() ));
}
sd_split.end_state_valid = true;
}
- sd_split.arms.push_back( {} );
+ if( reachable )
+ {
+ assert(m_block_active);
+ }
+ if( !early )
+ {
+ sd_split.arms.push_back( {} );
+ }
}
void MirBuilder::end_split_arm_early(const Span& sp)
{
TRACE_FUNCTION_F("");
size_t i = m_scope_stack.size();
- // Terminate all scopes until a split is found.
- while( i -- && ! (m_scopes.at(m_scope_stack[i]).data.is_Split() || m_scopes.at(m_scope_stack[i]).data.is_Loop()) )
+ // Terminate every sequence of owning scopes
+ while( i -- && m_scopes.at(m_scope_stack[i]).data.is_Owning() )
{
auto& scope_def = m_scopes[m_scope_stack[i]];
// Fully drop the scope
@@ -1529,6 +1500,7 @@ void MirBuilder::end_split_arm_early(const Span& sp)
// TODO: Create drop flags if required?
}
+ // TODO: What if this is a loop?
}
}
void MirBuilder::complete_scope(ScopeDef& sd)
@@ -1536,37 +1508,37 @@ void MirBuilder::complete_scope(ScopeDef& sd)
sd.complete = true;
TU_MATCHA( (sd.data), (e),
- (Temporaries,
- DEBUG("Temporaries - " << e.temporaries);
- ),
- (Variables,
- DEBUG("Variables - " << e.vars);
+ (Owning,
+ DEBUG("Owning (" << (e.is_temporary ? "temps" : "vars") << ") - " << e.slots);
),
(Loop,
DEBUG("Loop");
),
(Split,
+ ),
+ (Freeze,
+ //DEBUG("Freeze");
)
)
struct H {
static void apply_end_state(const Span& sp, MirBuilder& builder, SplitEnd& end_state)
{
- for(auto& ent : end_state.var_states)
+ for(auto& ent : end_state.states)
{
- auto& vs = builder.get_variable_state_mut(sp, ent.first);
+ auto& vs = builder.get_slot_state_mut(sp, ent.first, SlotType::Local);
if( vs != ent.second )
{
- DEBUG(::MIR::LValue::make_Variable(ent.first) << " " << vs << " => " << ent.second);
+ DEBUG(::MIR::LValue::make_Local(ent.first) << " " << vs << " => " << ent.second);
vs = ::std::move(ent.second);
}
}
- for(auto& ent : end_state.tmp_states)
+ for(auto& ent : end_state.arg_states)
{
- auto& vs = builder.get_temp_state_mut(sp, ent.first);
+ auto& vs = builder.get_slot_state_mut(sp, ent.first, SlotType::Argument);
if( vs != ent.second )
{
- DEBUG(::MIR::LValue::make_Temporary({ent.first}) << " " << vs << " => " << ent.second);
+ DEBUG(::MIR::LValue::make_Argument({ent.first}) << " " << vs << " => " << ent.second);
vs = ::std::move(ent.second);
}
}
@@ -1574,13 +1546,20 @@ void MirBuilder::complete_scope(ScopeDef& sd)
};
// No macro for better debug output.
- if( sd.data.is_Loop() )
+ if( auto* e = sd.data.opt_Loop() )
{
- auto& e = sd.data.as_Loop();
TRACE_FUNCTION_F("Loop");
- if( e.exit_state_valid )
+ if( e->exit_state_valid )
+ {
+ H::apply_end_state(sd.span, *this, e->exit_state);
+ }
+
+ // Insert sets of drop flags to the first block (at the start of that block)
+ auto& stmts = m_output.blocks.at(e->entry_bb).statements;
+ for(auto idx : e->drop_flags)
{
- H::apply_end_state(sd.span, *this, e.exit_state);
+ DEBUG("Reset df$" << idx);
+ stmts.insert( stmts.begin(), ::MIR::Statement::make_SetDropFlag({ idx, m_output.drop_flags.at(idx), ~0u }) );
}
}
else if( sd.data.is_Split() )
@@ -1596,16 +1575,15 @@ void MirBuilder::complete_scope(ScopeDef& sd)
void MirBuilder::with_val_type(const Span& sp, const ::MIR::LValue& val, ::std::function<void(const ::HIR::TypeRef&)> cb) const
{
TU_MATCH(::MIR::LValue, (val), (e),
- (Variable,
- cb( m_output.named_variables.at(e) );
- ),
- (Temporary,
- cb( m_output.temporaries.at(e.idx) );
+ (Return,
+ TODO(sp, "Return");
),
(Argument,
- ASSERT_BUG(sp, e.idx < m_args.size(), "Argument number out of range");
cb( m_args.at(e.idx).second );
),
+ (Local,
+ cb( m_output.locals.at(e) );
+ ),
(Static,
TU_MATCHA( (e.m_data), (pe),
(Generic,
@@ -1624,9 +1602,6 @@ void MirBuilder::with_val_type(const Span& sp, const ::MIR::LValue& val, ::std::
)
)
),
- (Return,
- TODO(sp, "Return");
- ),
(Field,
with_val_type(sp, *e.val, [&](const auto& ty){
TU_MATCH_DEF( ::HIR::TypeRef::Data, (ty.m_data), (te),
@@ -1821,7 +1796,7 @@ bool MirBuilder::lvalue_is_copy(const Span& sp, const ::MIR::LValue& val) const
return rv == 2;
}
-const VarState& MirBuilder::get_slot_state(const Span& sp, VarGroup ty, unsigned int idx, unsigned int skip_count/*=0*/) const
+const VarState& MirBuilder::get_slot_state(const Span& sp, unsigned int idx, SlotType type, unsigned int skip_count/*=0*/) const
{
// 1. Find an applicable Split scope
for( auto scope_idx : ::reverse(m_scope_stack) )
@@ -1830,146 +1805,114 @@ const VarState& MirBuilder::get_slot_state(const Span& sp, VarGroup ty, unsigned
TU_MATCH_DEF( ScopeType, (scope_def.data), (e),
(
),
- (Temporaries,
- if( ty == VarGroup::Temporary )
+ (Owning,
+ if( type == SlotType::Local )
{
- auto it = ::std::find(e.temporaries.begin(), e.temporaries.end(), idx);
- if( it != e.temporaries.end() ) {
- break ;
- }
- }
- ),
- (Variables,
- if( ty == VarGroup::Variable )
- {
- auto it = ::std::find(e.vars.begin(), e.vars.end(), idx);
- if( it != e.vars.end() ) {
- // If controlled by this block, exit early (won't find it elsewhere)
+ auto it = ::std::find(e.slots.begin(), e.slots.end(), idx);
+ if( it != e.slots.end() ) {
break ;
}
}
),
(Split,
const auto& cur_arm = e.arms.back();
- if( ty == VarGroup::Variable )
+ const auto& list = (type == SlotType::Local ? cur_arm.states : cur_arm.arg_states);
+ auto it = list.find(idx);
+ if( it != list.end() )
{
- auto it = cur_arm.var_states.find(idx);
- if( it != cur_arm.var_states.end() )
+ if( ! skip_count -- )
{
- if( ! skip_count -- )
- {
- return it->second;
- }
- }
- }
- else if( ty == VarGroup::Temporary )
- {
- auto it = cur_arm.tmp_states.find(idx);
- if( it != cur_arm.tmp_states.end() )
- {
- if( ! skip_count -- )
- {
- return it->second;
- }
+ return it->second;
}
}
)
)
}
- switch(ty)
+ switch(type)
{
- case VarGroup::Return:
- return m_return_state;
- case VarGroup::Argument:
+ case SlotType::Local:
+ if( idx == ~0u )
+ {
+ return m_return_state;
+ }
+ else
+ {
+ ASSERT_BUG(sp, idx < m_slot_states.size(), "Slot " << idx << " out of range for state table");
+ return m_slot_states.at(idx);
+ }
+ break;
+ case SlotType::Argument:
ASSERT_BUG(sp, idx < m_arg_states.size(), "Argument " << idx << " out of range for state table");
return m_arg_states.at(idx);
- case VarGroup::Variable:
- ASSERT_BUG(sp, idx < m_variable_states.size(), "Variable " << idx << " out of range for state table");
- return m_variable_states[idx];
- case VarGroup::Temporary:
- ASSERT_BUG(sp, idx < m_temporary_states.size(), "Temporary " << idx << " out of range for state table");
- return m_temporary_states[idx];
}
- BUG(sp, "Fell off the end of get_slot_state");
+ throw "";
}
-VarState& MirBuilder::get_slot_state_mut(const Span& sp, VarGroup ty, unsigned int idx)
+VarState& MirBuilder::get_slot_state_mut(const Span& sp, unsigned int idx, SlotType type)
{
VarState* ret = nullptr;
for( auto scope_idx : ::reverse(m_scope_stack) )
{
auto& scope_def = m_scopes.at(scope_idx);
- if( const auto* e = scope_def.data.opt_Variables() )
- {
- if( ty == VarGroup::Variable )
- {
- auto it = ::std::find(e->vars.begin(), e->vars.end(), idx);
- if( it != e->vars.end() ) {
- break ;
- }
- }
- }
- else if( const auto* e = scope_def.data.opt_Temporaries() )
+ if( const auto* e = scope_def.data.opt_Owning() )
{
- if( ty == VarGroup::Temporary )
+ if( type == SlotType::Local )
{
- auto it = ::std::find(e->temporaries.begin(), e->temporaries.end(), idx);
- if( it != e->temporaries.end() ) {
+ auto it = ::std::find(e->slots.begin(), e->slots.end(), idx);
+ if( it != e->slots.end() ) {
break ;
}
}
}
- else if( scope_def.data.is_Split() )
+ else if( auto* e = scope_def.data.opt_Split() )
{
- auto& e = scope_def.data.as_Split();
- auto& cur_arm = e.arms.back();
+ auto& cur_arm = e->arms.back();
if( ! ret )
{
- ::std::map<unsigned int, VarState>* states;
- switch(ty)
- {
- case VarGroup::Return: states = nullptr; break;
- case VarGroup::Argument: BUG(sp, "Mutating state of argument"); break;
- case VarGroup::Variable: states = &cur_arm.var_states; break;
- case VarGroup::Temporary: states = &cur_arm.tmp_states; break;
+ if( idx == ~0u ) {
}
-
- if( states )
- {
- auto it = states->find(idx);
- if( it == states->end() )
+ else {
+ auto& states = (type == SlotType::Local ? cur_arm.states : cur_arm.arg_states);
+ auto it = states.find(idx);
+ if( it == states.end() )
{
DEBUG("Split new (scope " << scope_idx << ")");
- ret = &( (*states)[idx] = get_slot_state(sp, ty, idx).clone() );
+ it = states.insert(::std::make_pair( idx, get_slot_state(sp, idx, type).clone() )).first;
}
else
{
DEBUG("Split existing (scope " << scope_idx << ")");
- ret = &it->second;
}
+ ret = &it->second;
}
}
}
- else if( scope_def.data.is_Loop() )
+ else if( auto* e = scope_def.data.opt_Loop() )
{
- auto& e = scope_def.data.as_Loop();
- ::std::map<unsigned int, VarState>* states = nullptr;
- switch(ty)
+ if( idx == ~0u )
{
- case VarGroup::Return: states = nullptr; break;
- case VarGroup::Argument: BUG(sp, "Mutating state of argument"); break;
- case VarGroup::Variable: states = &e.changed_vars; break;
- case VarGroup::Temporary: states = &e.changed_tmps; break;
}
-
- if( states )
+ else
{
- if( states->count(idx) == 0 )
+ auto& states = (type == SlotType::Local ? e->changed_slots : e->changed_args);
+ if( states.count(idx) == 0 )
{
- auto state = e.exit_state_valid ? get_slot_state(sp, ty, idx).clone() : VarState::make_Valid({});
- states->insert(::std::make_pair( idx, mv$(state) ));
+ auto state = e->exit_state_valid ? get_slot_state(sp, idx, type).clone() : VarState::make_Valid({});
+ states.insert(::std::make_pair( idx, mv$(state) ));
}
}
}
+ else if( scope_def.data.is_Freeze() )
+ {
+ if( type == SlotType::Local && idx == m_if_cond_lval.as_Local() )
+ {
+ }
+ else
+ {
+ // NOTE: This is only used in match conditions
+ DEBUG("Mutating state of ?" << idx);
+ ERROR(sp, E0000, "Attempting to move/initialise a value where not allowed");
+ }
+ }
else
{
}
@@ -1980,39 +1923,23 @@ VarState& MirBuilder::get_slot_state_mut(const Span& sp, VarGroup ty, unsigned i
}
else
{
- switch(ty)
+ switch(type)
{
- case VarGroup::Return:
- return m_return_state;
- case VarGroup::Argument:
- ASSERT_BUG(sp, idx < m_arg_states.size(), "Argument " << idx << " out of range for state table");
+ case SlotType::Local:
+ if( idx == ~0u )
+ {
+ return m_return_state;
+ }
+ else
+ {
+ return m_slot_states.at(idx);
+ }
+ case SlotType::Argument:
return m_arg_states.at(idx);
- case VarGroup::Variable:
- ASSERT_BUG(sp, idx < m_variable_states.size(), "Variable " << idx << " out of range for state table");
- return m_variable_states[idx];
- case VarGroup::Temporary:
- ASSERT_BUG(sp, idx < m_temporary_states.size(), "Temporary " << idx << " out of range for state table");
- return m_temporary_states[idx];
- }
- BUG(sp, "Fell off the end of get_slot_state_mut");
+ }
+ throw "";
}
}
-const VarState& MirBuilder::get_variable_state(const Span& sp, unsigned int idx, unsigned int skip_count) const
-{
- return get_slot_state(sp, VarGroup::Variable, idx, skip_count);
-}
-VarState& MirBuilder::get_variable_state_mut(const Span& sp, unsigned int idx)
-{
- return get_slot_state_mut(sp, VarGroup::Variable, idx);
-}
-const VarState& MirBuilder::get_temp_state(const Span& sp, unsigned int idx, unsigned int skip_count) const
-{
- return get_slot_state(sp, VarGroup::Temporary, idx, skip_count);
-}
-VarState& MirBuilder::get_temp_state_mut(const Span& sp, unsigned int idx)
-{
- return get_slot_state_mut(sp, VarGroup::Temporary, idx);
-}
const VarState& MirBuilder::get_val_state(const Span& sp, const ::MIR::LValue& lv, unsigned int skip_count)
{
@@ -2022,22 +1949,19 @@ VarState& MirBuilder::get_val_state_mut(const Span& sp, const ::MIR::LValue& lv)
{
TRACE_FUNCTION_F(lv);
TU_MATCHA( (lv), (e),
- (Variable,
- return get_slot_state_mut(sp, VarGroup::Variable, e);
- ),
- (Temporary,
- return get_slot_state_mut(sp, VarGroup::Temporary, e.idx);
+ (Return,
+ BUG(sp, "Move of return value");
+ return get_slot_state_mut(sp, ~0u, SlotType::Local);
),
(Argument,
- return get_slot_state_mut(sp, VarGroup::Argument, e.idx);
+ return get_slot_state_mut(sp, e.idx, SlotType::Argument);
+ ),
+ (Local,
+ return get_slot_state_mut(sp, e, SlotType::Local);
),
(Static,
BUG(sp, "Attempting to mutate state of a static");
),
- (Return,
- BUG(sp, "Move of return value");
- return get_slot_state_mut(sp, VarGroup::Return, 0);
- ),
(Field,
auto& ivs = get_val_state_mut(sp, *e.val);
VarState tpl;
@@ -2117,13 +2041,10 @@ VarState& MirBuilder::get_val_state_mut(const Span& sp, const ::MIR::LValue& lv)
this->push_stmt_assign(sp, inner_lv.clone(), ::MIR::RValue( mv$(*e.val) ));
*e.val = inner_lv.clone();
),
- (Variable,
- inner_lv = ::MIR::LValue(ei);
- ),
- (Temporary,
+ (Argument,
inner_lv = ::MIR::LValue(ei);
),
- (Argument,
+ (Local,
inner_lv = ::MIR::LValue(ei);
)
)
@@ -2252,20 +2173,12 @@ void MirBuilder::drop_value_from_state(const Span& sp, const VarState& vs, ::MIR
void MirBuilder::drop_scope_values(const ScopeDef& sd)
{
TU_MATCHA( (sd.data), (e),
- (Temporaries,
- for(auto tmp_idx : ::reverse(e.temporaries))
- {
- const auto& vs = get_temp_state(sd.span, tmp_idx);
- DEBUG("tmp" << tmp_idx << " - " << vs);
- drop_value_from_state( sd.span, vs, ::MIR::LValue::make_Temporary({ tmp_idx }) );
- }
- ),
- (Variables,
- for(auto var_idx : ::reverse(e.vars))
+ (Owning,
+ for(auto idx : ::reverse(e.slots))
{
- const auto& vs = get_variable_state(sd.span, var_idx);
- DEBUG("var" << var_idx << " - " << vs);
- drop_value_from_state( sd.span, vs, ::MIR::LValue::make_Variable(var_idx) );
+ const auto& vs = get_slot_state(sd.span, idx, SlotType::Local);
+ DEBUG("slot" << idx << " - " << vs);
+ drop_value_from_state( sd.span, vs, ::MIR::LValue::make_Local(idx) );
}
),
(Split,
@@ -2273,6 +2186,8 @@ void MirBuilder::drop_scope_values(const ScopeDef& sd)
),
(Loop,
// No values
+ ),
+ (Freeze,
)
)
}