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.cpp64
1 files changed, 42 insertions, 22 deletions
diff --git a/src/mir/mir_builder.cpp b/src/mir/mir_builder.cpp
index 473263b8..f41f6b91 100644
--- a/src/mir/mir_builder.cpp
+++ b/src/mir/mir_builder.cpp
@@ -576,7 +576,7 @@ ScopeHandle MirBuilder::new_scope_loop(const Span& sp)
}
void MirBuilder::terminate_scope(const Span& sp, ScopeHandle scope, bool emit_cleanup/*=true*/)
{
- DEBUG("DONE scope " << scope.idx << " - " << (emit_cleanup ? "CLEANUP" : "NO CLEANUP"));
+ TRACE_FUNCTION_F("DONE scope " << scope.idx << " - " << (emit_cleanup ? "CLEANUP" : "NO CLEANUP"));
// 1. Check that this is the current scope (at the top of the stack)
if( m_scope_stack.empty() || m_scope_stack.back() != scope.idx )
{
@@ -603,7 +603,7 @@ void MirBuilder::terminate_scope(const Span& sp, ScopeHandle scope, bool emit_cl
}
void MirBuilder::terminate_scope_early(const Span& sp, const ScopeHandle& scope)
{
- DEBUG("EARLY scope " << scope.idx);
+ TRACE_FUNCTION_F("EARLY scope " << scope.idx);
// 1. Ensure that this block is in the stack
auto it = ::std::find( m_scope_stack.begin(), m_scope_stack.end(), scope.idx );
@@ -649,10 +649,13 @@ void MirBuilder::end_split_arm(const Span& sp, const ScopeHandle& handle, bool r
auto& sd_split = sd.data.as_Split();
ASSERT_BUG(sp, !sd_split.arms.empty(), "");
+ TRACE_FUNCTION_F("end split scope " << handle.idx << " arm " << (sd_split.arms.size()-1));
+
sd_split.arms.back().always_early_terminated = /*sd_split.arms.back().has_early_terminated &&*/ !reachable;
// HACK: If this arm's end is reachable, convert InnerMoved (shallow drop) variable states to Moved
// - I'm not 100% sure this is the correct place for calling drop.
+ #if 1
if( reachable )
{
auto& vss = sd_split.arms.back().var_states;
@@ -660,23 +663,26 @@ void MirBuilder::end_split_arm(const Span& sp, const ScopeHandle& handle, bool r
{
auto& vs = vss[i];
if( vs == VarState::InnerMoved ) {
+ // TODO: Refactor InnerMoved to handle partial moves via Box
// Emit the shallow drop
- push_stmt_drop_shallow( sp, ::MIR::LValue::make_Variable(i) );
+ //push_stmt_drop_shallow( sp, ::MIR::LValue::make_Variable(i) );
vs = VarState::Moved;
}
}
}
+ #endif
sd_split.arms.push_back( {} );
}
void MirBuilder::end_split_arm_early(const Span& sp)
{
+ TRACE_FUNCTION_F("");
// Terminate all scopes until a split is found.
while( ! m_scope_stack.empty() && ! (m_scopes.at( m_scope_stack.back() ).data.is_Split() || m_scopes.at( m_scope_stack.back() ).data.is_Loop()) )
{
auto& scope_def = m_scopes[m_scope_stack.back()];
// Fully drop the scope
- DEBUG("Complete scope " << m_scope_stack.size()-1);
+ DEBUG("Complete scope " << m_scope_stack.back());
drop_scope_values(scope_def);
m_scope_stack.pop_back();
complete_scope(scope_def);
@@ -684,6 +690,7 @@ void MirBuilder::end_split_arm_early(const Span& sp)
if( !m_scope_stack.empty() && m_scopes.at( m_scope_stack.back() ).data.is_Split() )
{
+ DEBUG("Early terminate split scope " << m_scope_stack.back());
auto& sd = m_scopes[ m_scope_stack.back() ];
auto& sd_split = sd.data.as_Split();
sd_split.arms.back().has_early_terminated = true;
@@ -695,7 +702,7 @@ void MirBuilder::end_split_arm_early(const Span& sp)
if( vs == VarState::InnerMoved ) {
// Emit the shallow drop
push_stmt_drop_shallow( sp, ::MIR::LValue::make_Variable(i) );
- //vs = VarState::Dropped;
+ // - Don't update the state, because this drop isn't the end-of-scope drop
}
}
}
@@ -737,8 +744,8 @@ void MirBuilder::complete_scope(ScopeDef& sd)
switch( new_state )
{
case VarState::Uninit:
- BUG(sp, "Variable state changed from Uninit to Uninit (wut?)");
- break;
+ //BUG(sp, "Variable state changed from Uninit to Uninit (wut?)");
+ return VarState::Uninit;
case VarState::Init:
// TODO: MaybeInit?
return VarState::MaybeMoved;
@@ -747,7 +754,7 @@ void MirBuilder::complete_scope(ScopeDef& sd)
case VarState::Moved:
return VarState::Uninit;
case VarState::InnerMoved:
- TODO(sp, "Handle InnerMoved in Split scope (Init:arm.var_states)");
+ TODO(sp, "Handle InnerMoved in Split scope (Uninit:arm.var_states)");
break;
case VarState::Dropped:
BUG(sp, "Dropped value in arm");
@@ -768,7 +775,7 @@ void MirBuilder::complete_scope(ScopeDef& sd)
case VarState::Moved:
return VarState::MaybeMoved;
case VarState::InnerMoved:
- TODO(sp, "Handle InnerMoved in Split scope (Init:arm.var_states)");
+ TODO(sp, "Handle InnerMoved in Split scope (was Init)");
break;
case VarState::Dropped:
BUG(sp, "Dropped value in arm");
@@ -778,7 +785,21 @@ void MirBuilder::complete_scope(ScopeDef& sd)
case VarState::InnerMoved:
// Need to tag for conditional shallow drop? Or just do that at the end of the split?
// - End of the split means that the only optional state is outer drop.
- TODO(sp, "Handle InnerMoved in Split scope (new_states)");
+ switch( new_state )
+ {
+ case VarState::Uninit:
+ TODO(sp, "Handle InnerMoved in Split scope (new_states) - Now Uninit");
+ case VarState::Init:
+ TODO(sp, "Handle InnerMoved in Split scope (new_states) - Now Init");
+ case VarState::MaybeMoved:
+ TODO(sp, "Handle InnerMoved in Split scope (new_states) - Now MaybeMoved");
+ case VarState::Moved:
+ TODO(sp, "Handle InnerMoved in Split scope (new_states) - Now Moved");
+ case VarState::InnerMoved:
+ return VarState::InnerMoved;
+ case VarState::Dropped:
+ BUG(sp, "Dropped value in arm");
+ }
break;
case VarState::MaybeMoved:
// Already optional, don't change
@@ -787,8 +808,7 @@ void MirBuilder::complete_scope(ScopeDef& sd)
switch( new_state )
{
case VarState::Uninit:
- // Wut?
- break;
+ return VarState::Moved;
case VarState::Init:
// Wut? Reinited?
return VarState::MaybeMoved;
@@ -797,7 +817,7 @@ void MirBuilder::complete_scope(ScopeDef& sd)
case VarState::Moved:
return VarState::Moved;
case VarState::InnerMoved:
- TODO(sp, "Handle InnerMoved in Split scope (Moved:arm.var_states)");
+ TODO(sp, "Handle InnerMoved in Split scope (was Moved)");
break;
case VarState::Dropped:
BUG(sp, "Dropped value in arm");
@@ -808,7 +828,7 @@ void MirBuilder::complete_scope(ScopeDef& sd)
TODO(sp, "How can an arm drop a value?");
break;
}
- throw "";
+ BUG(sp, "Unhandled combination");
}
};
@@ -830,11 +850,11 @@ void MirBuilder::complete_scope(ScopeDef& sd)
changed_tmps.insert( i );
if( !first_arm )
first_arm = &arm;
-
+
var_count = ::std::max(var_count, arm.var_states.size());
tmp_count = ::std::max(tmp_count, arm.tmp_states.size());
}
-
+
if( !first_arm )
{
DEBUG("No arms yeilded");
@@ -843,7 +863,7 @@ void MirBuilder::complete_scope(ScopeDef& sd)
::std::vector<VarState> new_var_states { var_count };
::std::vector<VarState> new_tmp_states { tmp_count };
-
+
// 2. Build up the final composite state of the first arm
for(unsigned int i : changed_vars)
{
@@ -867,7 +887,7 @@ void MirBuilder::complete_scope(ScopeDef& sd)
new_tmp_states[i] = get_temp_state(sd.span, i);
}
}
-
+
// 3. Compare the rest of the arms
for(const auto& arm : e.arms)
{
@@ -1235,11 +1255,11 @@ void MirBuilder::drop_scope_values(const ScopeDef& sd)
break;
case VarState::Init:
push_stmt_drop( sd.span, ::MIR::LValue::make_Temporary({ tmp_idx }) );
- set_temp_state(sd.span, tmp_idx, VarState::Dropped);
+ //set_temp_state(sd.span, tmp_idx, VarState::Dropped);
break;
case VarState::InnerMoved:
push_stmt_drop_shallow( sd.span, ::MIR::LValue::make_Temporary({ tmp_idx }) );
- set_temp_state(sd.span, tmp_idx, VarState::Dropped);
+ //set_temp_state(sd.span, tmp_idx, VarState::Dropped);
break;
case VarState::MaybeMoved:
//BUG(sd.span, "Optionally moved temporary? - " << tmp_idx);
@@ -1261,11 +1281,11 @@ void MirBuilder::drop_scope_values(const ScopeDef& sd)
break;
case VarState::InnerMoved:
push_stmt_drop_shallow( sd.span, ::MIR::LValue::make_Variable(var_idx) );
- set_variable_state(sd.span, var_idx, VarState::Dropped);
+ //set_variable_state(sd.span, var_idx, VarState::Dropped);
break;
case VarState::MaybeMoved:
- //TODO(sd.span, "Include drop flags");
// TODO: Drop flags
+ //push_stmt_drop_opt(sd.span, ::MIR::LValue::make_Variable(var_idx), drop_flag_idx);
break;
}
}