summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mir/from_hir.cpp2
-rw-r--r--src/mir/from_hir.hpp17
-rw-r--r--src/mir/from_hir_match.cpp11
-rw-r--r--src/mir/helpers.cpp6
-rw-r--r--src/mir/mir_builder.cpp3
-rw-r--r--src/mir/optimise.cpp2
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;