diff options
author | John Hodge <tpg@ucc.asn.au> | 2017-04-22 22:05:27 +0800 |
---|---|---|
committer | John Hodge <tpg@ucc.asn.au> | 2017-04-22 22:05:27 +0800 |
commit | aea444c2dcceab61aa6632f014602bf7043e6a74 (patch) | |
tree | 802e954c838b837eb02791c6d984542107b41f81 /src | |
parent | 505090085f9264088963e724dc93edfde7e56b38 (diff) | |
download | mrust-aea444c2dcceab61aa6632f014602bf7043e6a74.tar.gz |
MIR Gen - Common lvalue for if
Diffstat (limited to 'src')
-rw-r--r-- | src/mir/from_hir.cpp | 2 | ||||
-rw-r--r-- | src/mir/from_hir.hpp | 17 | ||||
-rw-r--r-- | src/mir/from_hir_match.cpp | 11 | ||||
-rw-r--r-- | src/mir/helpers.cpp | 6 | ||||
-rw-r--r-- | src/mir/mir_builder.cpp | 3 | ||||
-rw-r--r-- | src/mir/optimise.cpp | 2 |
6 files changed, 33 insertions, 8 deletions
diff --git a/src/mir/from_hir.cpp b/src/mir/from_hir.cpp index f3f8f745..04291799 100644 --- a/src/mir/from_hir.cpp +++ b/src/mir/from_hir.cpp @@ -750,7 +750,7 @@ namespace { auto scope = m_builder.new_scope_temp( cond->span() ); this->visit_node_ptr(*cond_p); ASSERT_BUG(cond->span(), cond->m_res_type == ::HIR::CoreType::Bool, "If condition wasn't a bool"); - decision_val = m_builder.get_result_in_lvalue(cond->span(), ::HIR::CoreType::Bool); + decision_val = m_builder.get_result_in_if_cond(cond->span()); m_builder.terminate_scope(cond->span(), mv$(scope)); } diff --git a/src/mir/from_hir.hpp b/src/mir/from_hir.hpp index e124770c..07228688 100644 --- a/src/mir/from_hir.hpp +++ b/src/mir/from_hir.hpp @@ -159,6 +159,11 @@ class MirBuilder ::std::vector<ScopeDef> m_scopes; ::std::vector<unsigned int> m_scope_stack; ScopeHandle m_fcn_scope; + + // LValue used only for the condition of `if` + // - Using a fixed temporary simplifies parts of lowering (scope related) and reduces load on + // the optimiser. + ::MIR::LValue m_if_cond_lval; public: MirBuilder(const Span& sp, const StaticTraitResolve& resolve, const ::HIR::Function::args_t& args, ::MIR::Function& output); ~MirBuilder(); @@ -186,6 +191,17 @@ public: /// Obtains a result in a param (or a lvalue) ::MIR::Param get_result_in_param(const Span& sp, const ::HIR::TypeRef& ty, bool allow_missing_value=false); + ::MIR::LValue get_if_cond() const { + return m_if_cond_lval.clone(); + } + ::MIR::LValue get_rval_in_if_cond(const Span& sp, ::MIR::RValue val) { + push_stmt_assign(sp, m_if_cond_lval.clone(), mv$(val)); + return m_if_cond_lval.clone(); + } + ::MIR::LValue get_result_in_if_cond(const Span& sp) { + return get_rval_in_if_cond(sp, get_result(sp)); + } + // - Statements // Push an assignment. NOTE: This also marks the rvalue as moved void push_stmt_assign(const Span& sp, ::MIR::LValue dst, ::MIR::RValue val); @@ -215,6 +231,7 @@ public: void set_cur_block(unsigned int new_block); ::MIR::BasicBlockId pause_cur_block(); + void end_block(::MIR::Terminator term); ::MIR::BasicBlockId new_bb_linked(); diff --git a/src/mir/from_hir_match.cpp b/src/mir/from_hir_match.cpp index 2f248f10..ec720d8a 100644 --- a/src/mir/from_hir_match.cpp +++ b/src/mir/from_hir_match.cpp @@ -372,8 +372,7 @@ void MIR_LowerHIR_Match( MirBuilder& builder, MirConverter& conv, ::HIR::ExprNod auto tmp_scope = builder.new_scope_temp(arm.m_cond->span()); conv.visit_node_ptr( arm.m_cond ); - ac.cond_lval = builder.get_result_in_lvalue(arm.m_cond->span(), ::HIR::TypeRef(::HIR::CoreType::Bool)); - // NOTE: Terminating the scope slightly early is safe, because the resulting boolean temp isn't invalidated. + ac.cond_lval = builder.get_result_in_if_cond(arm.m_cond->span()); builder.terminate_scope( arm.m_code->span(), mv$(tmp_scope) ); ac.cond_end = builder.pause_cur_block(); @@ -1947,8 +1946,8 @@ int MIR_LowerHIR_Match_Simple__GeneratePattern(MirBuilder& builder, const Span& auto succ_bb = builder.new_bb_unlinked(); auto test_val = ::MIR::Param( ::MIR::Constant::make_Uint({ re.as_Uint().v, te })); - auto cmp_lval = builder.lvalue_or_temp(sp, ::HIR::CoreType::Bool, ::MIR::RValue::make_BinOp({ val.clone(), ::MIR::eBinOp::EQ, mv$(test_val) })); - builder.end_block( ::MIR::Terminator::make_If({ mv$(cmp_lval), succ_bb, fail_bb }) ); + builder.push_stmt_assign(sp, builder.get_if_cond(), ::MIR::RValue::make_BinOp({ val.clone(), ::MIR::eBinOp::EQ, mv$(test_val) })); + builder.end_block( ::MIR::Terminator::make_If({ builder.get_if_cond(), succ_bb, fail_bb }) ); builder.set_cur_block(succ_bb); ), (ValueRange, @@ -2847,8 +2846,8 @@ void MatchGenGrouped::gen_dispatch__primitive(::HIR::TypeRef ty, ::MIR::LValue v ASSERT_BUG(sp, r.is_Value(), "Matching without _Value pattern - " << r.tag_str()); const auto& re = r.as_Value(); auto test_val = ::MIR::Param(re.clone()); - auto cmp_lval = this->push_compare( val.clone(), ::MIR::eBinOp::EQ, mv$(test_val) ); - m_builder.end_block( ::MIR::Terminator::make_If({ mv$(cmp_lval), arm_targets[0], def_blk }) ); + auto cmp_lval = m_builder.get_rval_in_if_cond(sp, ::MIR::RValue::make_BinOp({ val.clone(), ::MIR::eBinOp::EQ, mv$(test_val) })); + m_builder.end_block( ::MIR::Terminator::make_If({ mv$(cmp_lval), arm_targets[0], def_blk }) ); } else { diff --git a/src/mir/helpers.cpp b/src/mir/helpers.cpp index 21e16116..d70fda95 100644 --- a/src/mir/helpers.cpp +++ b/src/mir/helpers.cpp @@ -502,6 +502,9 @@ namespace { bool is_empty() const { return start == end; } + bool is_borrowed() const { + return this->end == Position { ~0u, ~0u }; + } }; static unsigned NEXT_INDEX = 0; struct State @@ -585,10 +588,11 @@ namespace { { // TODO: This logic isn't quite correct. Just becase a value's existing end is already marked as valid, // doesn't mean that we have no new information. + // - Wait, doesn't it? auto try_merge_lft = [&](const ProtoLifetime& lft, const ::std::vector<unsigned int>& seen)->bool { if(lft.is_empty()) return false; // TODO: What should be done for borrow flagged values - if(lft.end == Position { ~0u, ~0u }) return false; + if(lft.is_borrowed()) return false; auto end_idx = block_offsets.at( val_state.block_path.at(lft.end.path_index) ) + lft.end.stmt_idx; auto it = ::std::find(seen.begin(), seen.end(), end_idx); diff --git a/src/mir/mir_builder.cpp b/src/mir/mir_builder.cpp index c023b797..293904df 100644 --- a/src/mir/mir_builder.cpp +++ b/src/mir/mir_builder.cpp @@ -32,6 +32,9 @@ MirBuilder::MirBuilder(const Span& sp, const StaticTraitResolve& resolve, const m_scopes.push_back( ScopeDef { sp, ScopeType::make_Temporaries({}) } ); m_scope_stack.push_back( 1 ); + + 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({}) ); diff --git a/src/mir/optimise.cpp b/src/mir/optimise.cpp index f66b3240..611b3a9e 100644 --- a/src/mir/optimise.cpp +++ b/src/mir/optimise.cpp @@ -1121,6 +1121,8 @@ bool MIR_Optimise_UnifyTemporaries(::MIR::TypeResolve& state, ::MIR::Function& f } return false; }); + + // TODO: Replace in ScopeEnd too? } return replacement_needed; |