diff options
author | John Hodge <tpg@mutabah.net> | 2016-12-27 19:28:08 +1100 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2016-12-27 19:28:08 +1100 |
commit | 15e14449ba15e234e99a231473c65cdf92ff76af (patch) | |
tree | e7e2ff7fb7f221bf40f000c92265a76bb698a298 | |
parent | 2ed96df45da794801df31f14111807beb31fc59d (diff) | |
download | mrust-15e14449ba15e234e99a231473c65cdf92ff76af.tar.gz |
MIR Gen - Misc fixes
-rw-r--r-- | src/mir/from_hir.cpp | 14 | ||||
-rw-r--r-- | src/mir/from_hir_match.cpp | 9 | ||||
-rw-r--r-- | src/mir/mir_builder.cpp | 64 |
3 files changed, 60 insertions, 27 deletions
diff --git a/src/mir/from_hir.cpp b/src/mir/from_hir.cpp index 288a724a..bdc3dda2 100644 --- a/src/mir/from_hir.cpp +++ b/src/mir/from_hir.cpp @@ -1415,7 +1415,19 @@ namespace { for(auto& arg : node.m_args) { this->visit_node_ptr(arg); - values.push_back( m_builder.get_result_in_lvalue(arg->span(), arg->m_res_type) ); + + if( node.m_args.size() == 1 ) + { + values.push_back( m_builder.get_result_in_lvalue(arg->span(), arg->m_res_type) ); + } + else + { + // NOTE: Have to allocate a new temporary because ordering matters + auto tmp = m_builder.new_temporary(arg->m_res_type); + m_builder.push_stmt_assign( arg->span(), tmp.clone(), m_builder.get_result(arg->span()) ); + values.push_back( mv$(tmp) ); + } + m_builder.moved_lvalue( arg->span(), values.back() ); } diff --git a/src/mir/from_hir_match.cpp b/src/mir/from_hir_match.cpp index 4d61da73..78382db3 100644 --- a/src/mir/from_hir_match.cpp +++ b/src/mir/from_hir_match.cpp @@ -120,8 +120,9 @@ void MIR_LowerHIR_Match( MirBuilder& builder, MirConverter& conv, ::HIR::ExprNod auto next_block = builder.new_bb_unlinked(); // 1. Stop the current block so we can generate code - auto first_cmp_block = builder.new_bb_unlinked(); - builder.end_block( ::MIR::Terminator::make_Goto(first_cmp_block) ); + //auto first_cmp_block = builder.new_bb_unlinked(); + //builder.end_block( ::MIR::Terminator::make_Goto(first_cmp_block) ); + auto first_cmp_block = builder.pause_cur_block(); struct H { @@ -242,7 +243,7 @@ void MIR_LowerHIR_Match( MirBuilder& builder, MirConverter& conv, ::HIR::ExprNod t_arm_rules arm_rules; for(unsigned int arm_idx = 0; arm_idx < node.m_arms.size(); arm_idx ++) { - DEBUG("ARM " << arm_idx); + TRACE_FUNCTION_FR("ARM " << arm_idx, "ARM" << arm_idx); /*const*/ auto& arm = node.m_arms[arm_idx]; ArmCode ac; @@ -272,7 +273,7 @@ void MIR_LowerHIR_Match( MirBuilder& builder, MirConverter& conv, ::HIR::ExprNod ac.destructures.push_back( builder.new_bb_unlinked() ); builder.set_cur_block( ac.destructures.back() ); conv.destructure_from( arm.m_code->span(), pat, match_val.clone(), true ); - builder.end_split_arm( arm.m_code->span(), pat_scope, true ); + builder.end_split_arm( arm.m_code->span(), pat_scope, /*reachable=*/false ); // HACK: Mark as not reachable, this scope isn't for codegen. builder.pause_cur_block(); // NOTE: Paused block resumed upon successful match } 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; } } |