diff options
author | John Hodge <tpg@ucc.asn.au> | 2017-07-06 16:29:30 +0800 |
---|---|---|
committer | John Hodge <tpg@ucc.asn.au> | 2017-07-06 16:29:30 +0800 |
commit | c4e88b3c49736e71534c918a83956885c052beb8 (patch) | |
tree | ec829a8e30c2242cf3ac964b5edc473f2af06db7 | |
parent | 3afff6d92dd9806a6dc1e86e3dbdbf56577c6a8a (diff) | |
download | mrust-c4e88b3c49736e71534c918a83956885c052beb8.tar.gz |
MIR - Add (but don't use) a SwitchValue terminator
-rw-r--r-- | src/hir/serialise.cpp | 24 | ||||
-rw-r--r-- | src/hir_conv/bind.cpp | 3 | ||||
-rw-r--r-- | src/mir/check.cpp | 17 | ||||
-rw-r--r-- | src/mir/check_full.cpp | 8 | ||||
-rw-r--r-- | src/mir/cleanup.cpp | 3 | ||||
-rw-r--r-- | src/mir/dump.cpp | 18 | ||||
-rw-r--r-- | src/mir/helpers.cpp | 10 | ||||
-rw-r--r-- | src/mir/mir.cpp | 34 | ||||
-rw-r--r-- | src/mir/mir.hpp | 14 | ||||
-rw-r--r-- | src/mir/optimise.cpp | 263 | ||||
-rw-r--r-- | src/trans/codegen_c.cpp | 9 | ||||
-rw-r--r-- | src/trans/codegen_c_structured.cpp | 8 | ||||
-rw-r--r-- | src/trans/enumerate.cpp | 6 | ||||
-rw-r--r-- | src/trans/monomorphise.cpp | 8 |
14 files changed, 259 insertions, 166 deletions
diff --git a/src/hir/serialise.cpp b/src/hir/serialise.cpp index cddbf0b8..78efe261 100644 --- a/src/hir/serialise.cpp +++ b/src/hir/serialise.cpp @@ -77,6 +77,9 @@ namespace { m_out.write_count(e.first); serialise(e.second); } + //void serialise(::MIR::BasicBlockId val) { + // m_out.write_count(val); + //} void serialise_type(const ::HIR::TypeRef& ty) { @@ -531,6 +534,12 @@ namespace { for(auto t : e.targets) m_out.write_count(t); ), + (SwitchValue, + serialise(e.val); + m_out.write_count(e.def_target); + serialise_vec(e.targets); + serialise(e.values); + ), (Call, m_out.write_count(e.ret_block); m_out.write_count(e.panic_block); @@ -540,6 +549,21 @@ namespace { ) ) } + void serialise(const ::MIR::SwitchValues& sv) + { + m_out.write_tag( static_cast<int>(sv.tag()) ); + TU_MATCHA( (sv), (e), + (Unsigned, + serialise_vec(e); + ), + (Signed, + serialise_vec(e); + ), + (String, + serialise_vec(e); + ) + ) + } void serialise(const ::MIR::CallTarget& ct) { m_out.write_tag( static_cast<int>(ct.tag()) ); diff --git a/src/hir_conv/bind.cpp b/src/hir_conv/bind.cpp index 1b0f61b6..beac3b84 100644 --- a/src/hir_conv/bind.cpp +++ b/src/hir_conv/bind.cpp @@ -617,6 +617,9 @@ namespace { (Switch, H::visit_lvalue(*this, te.val); ), + (SwitchValue, + H::visit_lvalue(*this, te.val); + ), (Call, H::visit_lvalue(*this, te.ret_val); TU_MATCHA( (te.fcn), (e2), diff --git a/src/mir/check.cpp b/src/mir/check.cpp index 58bcaf55..7c0cd4d8 100644 --- a/src/mir/check.cpp +++ b/src/mir/check.cpp @@ -452,6 +452,14 @@ void MIR_Validate_ValState(::MIR::TypeResolve& state, const ::MIR::Function& fcn add_to_visit( tgt, path, val_state ); } ), + (SwitchValue, + val_state.ensure_valid( state, e.val ); + for(const auto& tgt : e.targets) + { + add_to_visit( tgt, path, val_state ); + } + add_to_visit( e.def_target, path, val_state ); + ), (Call, if( e.fcn.is_Value() ) val_state.ensure_valid( state, e.fcn.as_Value() ); @@ -534,6 +542,12 @@ void MIR_Validate(const StaticTraitResolve& resolve, const ::HIR::ItemPath& path PUSH_BB(e.targets[i], "Switch V" << i); } ), + (SwitchValue, + for(unsigned int i = 0; i < e.targets.size(); i++ ) { + PUSH_BB(e.targets[i], "SwitchValue " << i); + } + PUSH_BB(e.def_target, "SwitchValue def"); + ), (Call, PUSH_BB(e.ret_block, "Call ret"); PUSH_BB(e.panic_block, "Call panic"); @@ -829,6 +843,9 @@ void MIR_Validate(const StaticTraitResolve& resolve, const ::HIR::ItemPath& path (Switch, // Check that the condition is an enum ), + (SwitchValue, + // Check that the condition's type matches the values + ), (Call, if( e.fcn.is_Value() ) { diff --git a/src/mir/check_full.cpp b/src/mir/check_full.cpp index a153aca7..1f86c40a 100644 --- a/src/mir/check_full.cpp +++ b/src/mir/check_full.cpp @@ -995,6 +995,14 @@ void MIR_Validate_FullValState(::MIR::TypeResolve& mir_res, const ::MIR::Functio todo_queue.push_back( ::std::make_pair(te.targets[i], i == te.targets.size()-1 ? mv$(state) : state.clone()) ); } ), + (SwitchValue, + state.ensure_lvalue_valid(mir_res, te.val); + for(size_t i = 0; i < te.targets.size(); i ++) + { + todo_queue.push_back( ::std::make_pair(te.targets[i], state.clone()) ); + } + todo_queue.push_back( ::std::make_pair(te.def_target, mv$(state)) ); + ), (Call, if(const auto* e = te.fcn.opt_Value()) { diff --git a/src/mir/cleanup.cpp b/src/mir/cleanup.cpp index 3dda81dc..f26f2bdd 100644 --- a/src/mir/cleanup.cpp +++ b/src/mir/cleanup.cpp @@ -1103,6 +1103,9 @@ void MIR_Cleanup(const StaticTraitResolve& resolve, const ::HIR::ItemPath& path, (Switch, MIR_Cleanup_LValue(state, mutator, e.val); ), + (SwitchValue, + MIR_Cleanup_LValue(state, mutator, e.val); + ), (Call, MIR_Cleanup_LValue(state, mutator, e.ret_val); if( e.fcn.is_Value() ) { diff --git a/src/mir/dump.cpp b/src/mir/dump.cpp index 4e53cf5b..a029023a 100644 --- a/src/mir/dump.cpp +++ b/src/mir/dump.cpp @@ -131,6 +131,24 @@ namespace { m_os << j << " => bb" << e.targets[j] << ", "; m_os << "}\n"; ), + (SwitchValue, + m_os << "switch " << FMT_M(e.val) << " {"; + TU_MATCHA( (e.values), (ve), + (Unsigned, + for(unsigned int j = 0; j < e.targets.size(); j ++) + m_os << ve[j] << " => bb" << e.targets[j] << ", "; + ), + (Signed, + for(unsigned int j = 0; j < e.targets.size(); j ++) + m_os << (ve[j] >= 0 ? "+" : "") << ve[j] << " => bb" << e.targets[j] << ", "; + ), + (String, + for(unsigned int j = 0; j < e.targets.size(); j ++) + m_os << "\"" << ve[j] << "\" => bb" << e.targets[j] << ", "; + ) + ) + m_os << "_ => bb" << e.def_target << "}\n"; + ), (Call, m_os << FMT_M(e.ret_val) << " = "; TU_MATCHA( (e.fcn), (e2), diff --git a/src/mir/helpers.cpp b/src/mir/helpers.cpp index ea5709d1..e51c9180 100644 --- a/src/mir/helpers.cpp +++ b/src/mir/helpers.cpp @@ -481,6 +481,9 @@ namespace visit { (Switch, rv |= visit_mir_lvalue(e.val, ValUsage::Read, cb); ), + (SwitchValue, + rv |= visit_mir_lvalue(e.val, ValUsage::Read, cb); + ), (Call, if( e.fcn.is_Value() ) { rv |= visit_mir_lvalue(e.fcn.as_Value(), ValUsage::Read, cb); @@ -951,6 +954,13 @@ void MIR_Helper_GetLifetimes_DetermineValueLifetime( m_states_to_do.push_back( ::std::make_pair(te.targets[i], mv$(s)) ); } ), + (SwitchValue, + for(size_t i = 0; i < te.targets.size(); i ++) + { + m_states_to_do.push_back( ::std::make_pair(te.targets[i], state.clone()) ); + } + m_states_to_do.push_back( ::std::make_pair(te.def_target, mv$(state)) ); + ), (Call, if( te.ret_val == m_lv ) { diff --git a/src/mir/mir.cpp b/src/mir/mir.cpp index 3f7057ff..09e978f9 100644 --- a/src/mir/mir.cpp +++ b/src/mir/mir.cpp @@ -419,6 +419,24 @@ namespace MIR { os << j << " => bb" << e.targets[j] << ", "; os << ")"; ), + (SwitchValue, + os << "SwitchValue( " << e.val << " : "; + TU_MATCHA( (e.values), (ve), + (Unsigned, + for(unsigned int j = 0; j < e.targets.size(); j ++) + os << ve[j] << " => bb" << e.targets[j] << ", "; + ), + (Signed, + for(unsigned int j = 0; j < e.targets.size(); j ++) + os << (ve[j] >= 0 ? "+" : "") << ve[j] << " => bb" << e.targets[j] << ", "; + ), + (String, + for(unsigned int j = 0; j < e.targets.size(); j ++) + os << "\"" << ve[j] << "\" => bb" << e.targets[j] << ", "; + ) + ) + os << "else bb" << e.def_target << ")"; + ), (Call, os << "Call( " << e.ret_val << " = "; TU_MATCHA( (e.fcn), (e2), @@ -604,3 +622,19 @@ namespace MIR { throw ""; } +::MIR::SwitchValues MIR::SwitchValues::clone() const +{ + TU_MATCHA( (*this), (ve), + (Unsigned, + return ve; + ), + (Signed, + return ve; + ), + (String, + return ve; + ) + ) + throw ""; +} + diff --git a/src/mir/mir.hpp b/src/mir/mir.hpp index 6254bf42..987e0498 100644 --- a/src/mir/mir.hpp +++ b/src/mir/mir.hpp @@ -211,6 +211,14 @@ TAGGED_UNION(CallTarget, Intrinsic, ::HIR::PathParams params; }) ); +TAGGED_UNION_EX(SwitchValues, (), Unsigned, ( + (Unsigned, ::std::vector<uint64_t>), + (Signed, ::std::vector<int64_t>), + (String, ::std::vector<::std::string>) + ), (),(), ( + SwitchValues clone() const; + ) + ); TAGGED_UNION(Terminator, Incomplete, (Incomplete, struct {}), // Block isn't complete (ERROR in output) @@ -227,6 +235,12 @@ TAGGED_UNION(Terminator, Incomplete, LValue val; ::std::vector<BasicBlockId> targets; }), + (SwitchValue, struct { + LValue val; + BasicBlockId def_target; + ::std::vector<BasicBlockId> targets; + SwitchValues values; + }), (Call, struct { BasicBlockId ret_block; BasicBlockId panic_block; diff --git a/src/mir/optimise.cpp b/src/mir/optimise.cpp index 3ef629b1..73cbaa04 100644 --- a/src/mir/optimise.cpp +++ b/src/mir/optimise.cpp @@ -222,6 +222,9 @@ namespace { (Switch, visit_mir_lvalue_mut(e.val, ValUsage::Read, cb); ), + (SwitchValue, + visit_mir_lvalue_mut(e.val, ValUsage::Read, cb); + ), (Call, if( e.fcn.is_Value() ) { visit_mir_lvalue_mut(e.fcn.as_Value(), ValUsage::Read, cb); @@ -392,6 +395,42 @@ namespace { } + void visit_terminator_target_mut(::MIR::Terminator& term, ::std::function<void(::MIR::BasicBlockId&)> cb) { + TU_MATCHA( (term), (e), + (Incomplete, + ), + (Return, + ), + (Diverge, + ), + (Goto, + cb(e); + ), + (Panic, + ), + (If, + cb(e.bb0); + cb(e.bb1); + ), + (Switch, + for(auto& target : e.targets) + cb(target); + ), + (SwitchValue, + for(auto& target : e.targets) + cb(target); + cb(e.def_target); + ), + (Call, + cb(e.ret_block); + cb(e.panic_block); + ) + ) + } + void visit_terminator_target(const ::MIR::Terminator& term, ::std::function<void(const ::MIR::BasicBlockId&)> cb) { + visit_terminator_target_mut(const_cast<::MIR::Terminator&>(term), cb); + } + void visit_blocks_mut(::MIR::TypeResolve& state, ::MIR::Function& fcn, ::std::function<void(::MIR::BasicBlockId, ::MIR::BasicBlock&)> cb) { ::std::vector<bool> visited( fcn.blocks.size() ); @@ -406,44 +445,16 @@ namespace { cb(bb, block); - TU_MATCHA( (block.terminator), (e), - (Incomplete, - ), - (Return, - ), - (Diverge, - ), - (Goto, + visit_terminator_target(block.terminator, [&](auto e){ if( !visited[e] ) to_visit.push_back(e); - ), - (Panic, - ), - (If, - if( !visited[e.bb0] ) - to_visit.push_back(e.bb0); - if( !visited[e.bb1] ) - to_visit.push_back(e.bb1); - ), - (Switch, - for(auto& target : e.targets) - if( !visited[target] ) - to_visit.push_back(target); - ), - (Call, - if( !visited[e.ret_block] ) - to_visit.push_back(e.ret_block); - if( !visited[e.panic_block] ) - to_visit.push_back(e.panic_block); - ) - ) + }); } } void visit_blocks(::MIR::TypeResolve& state, const ::MIR::Function& fcn, ::std::function<void(::MIR::BasicBlockId, const ::MIR::BasicBlock&)> cb) { visit_blocks_mut(state, const_cast<::MIR::Function&>(fcn), [cb](auto id, auto& blk){ cb(id, blk); }); } - bool statement_invalidates_lvalue(const ::MIR::Statement& stmt, const ::MIR::LValue& lv) { return visit_mir_lvalues(stmt, [&](const auto& v, auto vu) { @@ -651,32 +662,10 @@ bool MIR_Optimise_BlockSimplify(::MIR::TypeResolve& state, ::MIR::Function& fcn) } } - TU_MATCHA( (block.terminator), (e), - (Incomplete, - ), - (Return, - ), - (Diverge, - ), - (Goto, + visit_terminator_target_mut(block.terminator, [&](auto& e) { if( &fcn.blocks[e] != &block ) e = get_new_target(state, e); - ), - (Panic, - ), - (If, - e.bb0 = get_new_target(state, e.bb0); - e.bb1 = get_new_target(state, e.bb1); - ), - (Switch, - for(auto& target : e.targets) - target = get_new_target(state, target); - ), - (Call, - e.ret_block = get_new_target(state, e.ret_block); - e.panic_block = get_new_target(state, e.panic_block); - ) - ) + }); } // >> Merge blocks where a block goto-s to a single-use block. @@ -694,40 +683,10 @@ bool MIR_Optimise_BlockSimplify(::MIR::TypeResolve& state, ::MIR::Function& fcn) visited[bb] = true; const auto& block = fcn.blocks[bb]; - TU_MATCHA( (block.terminator), (e), - (Incomplete, - ), - (Return, - ), - (Diverge, - ), - (Goto, + visit_terminator_target(block.terminator, [&](const auto& e) { if( !visited[e] ) to_visit.push_back(e); uses[e] ++; - ), - (Panic, - ), - (If, - if( !visited[e.bb0] ) to_visit.push_back(e.bb0); - if( !visited[e.bb1] ) to_visit.push_back(e.bb1); - uses[e.bb0] ++; - uses[e.bb1] ++; - ), - (Switch, - for(auto& target : e.targets) - { - if( !visited[target] ) - to_visit.push_back(target); - uses[target] ++; - } - ), - (Call, - if( !visited[e.ret_block] ) to_visit.push_back(e.ret_block); - if( !visited[e.panic_block] ) to_visit.push_back(e.panic_block); - uses[e.ret_block] ++; - uses[e.panic_block] ++; - ) - ) + }); } unsigned int i = 0; @@ -970,6 +929,13 @@ bool MIR_Optimise_Inlining(::MIR::TypeResolve& state, ::MIR::Function& fcn, bool arms.push_back( bbi + this->bb_base ); return ::MIR::Terminator::make_Switch({ this->clone_lval(se.val), mv$(arms) }); ), + (SwitchValue, + ::std::vector<::MIR::BasicBlockId> arms; + arms.reserve(se.targets.size()); + for(const auto& bbi : se.targets) + arms.push_back( bbi + this->bb_base ); + return ::MIR::Terminator::make_SwitchValue({ this->clone_lval(se.val), se.def_target + this->bb_base, mv$(arms), se.values.clone() }); + ), (Call, ::MIR::CallTarget tgt; TU_MATCHA( (se.fcn), (ste), @@ -1412,6 +1378,30 @@ bool MIR_Optimise_UnifyBlocks(::MIR::TypeResolve& state, ::MIR::Function& fcn) if( ae.targets != be.targets ) return false; ), + (SwitchValue, + if( ae.val != be.val ) + return false; + if( ae.targets != be.targets ) + return false; + if( ae.def_target != be.def_target ) + return false; + if( ae.values.tag() != be.values.tag() ) + return false; + TU_MATCHA( (ae.values, be.values), (ae2, be2), + (Unsigned, + if( ae2 != be2 ) + return false; + ), + (Signed, + if( ae2 != be2 ) + return false; + ), + (String, + if( ae2 != be2 ) + return false; + ) + ) + ), (Call, if( ae.ret_block != be.ret_block ) return false; @@ -1483,32 +1473,9 @@ bool MIR_Optimise_UnifyBlocks(::MIR::TypeResolve& state, ::MIR::Function& fcn) { if( bb.terminator.tag() == ::MIR::Terminator::TAGDEAD ) continue ; - TU_MATCHA( (bb.terminator), (te), - (Incomplete, - ), - (Return, - ), - (Diverge, - ), - (Goto, + visit_terminator_target_mut(bb.terminator, [&](auto& te) { patch_tgt(te); - ), - (Panic, - patch_tgt(te.dst); - ), - (If, - patch_tgt(te.bb0); - patch_tgt(te.bb1); - ), - (Switch, - for(auto& tgt : te.targets) - patch_tgt(tgt); - ), - (Call, - patch_tgt(te.ret_block); - patch_tgt(te.panic_block); - ) - ) + }); //DEBUG("- " << bb.terminator); } @@ -1548,7 +1515,7 @@ bool MIR_Optimise_PropagateKnownValues(::MIR::TypeResolve& state, ::MIR::Functio visited[bb] = true; const auto& block = fcn.blocks[bb]; - auto ref_block = [&](auto idx) { + visit_terminator_target(block.terminator, [&](const auto& idx) { if( !visited[idx] ) to_visit.push_back(idx); if(block_uses[idx] == 0) @@ -1556,34 +1523,7 @@ bool MIR_Optimise_PropagateKnownValues(::MIR::TypeResolve& state, ::MIR::Functio else block_origins[idx] = SIZE_MAX; block_uses[idx] ++; - }; - TU_MATCHA( (block.terminator), (e), - (Incomplete, - ), - (Return, - ), - (Diverge, - ), - (Goto, - ref_block(e); - ), - (Panic, - ), - (If, - ref_block(e.bb0); - ref_block(e.bb1); - ), - (Switch, - for(auto& target : e.targets) - { - ref_block(target); - } - ), - (Call, - ref_block(e.ret_block); - ref_block(e.panic_block); - ) - ) + }); } } @@ -2293,6 +2233,11 @@ bool MIR_Optimise_PropagateSingleAssignments(::MIR::TypeResolve& state, ::MIR::F found = true; stop = true; ), + (SwitchValue, + if( src_is_lvalue && visit_mir_lvalue(e.val, ValUsage::Read, is_lvalue_usage) ) + found = true; + stop = true; + ), (Call, if( e.fcn.is_Value() ) if( src_is_lvalue && visit_mir_lvalue(e.fcn.as_Value(), ValUsage::Read, is_lvalue_usage) ) @@ -2847,6 +2792,12 @@ bool MIR_Optimise_GarbageCollect(::MIR::TypeResolve& state, ::MIR::Function& fcn for(auto& target : e.targets) target = block_rewrite_table[target]; ), + (SwitchValue, + visit_mir_lvalue_mut(e.val, ValUsage::Read, lvalue_cb); + for(auto& target : e.targets) + target = block_rewrite_table[target]; + e.def_target = block_rewrite_table[e.def_target]; + ), (Call, if( e.fcn.is_Value() ) { visit_mir_lvalue_mut(e.fcn.as_Value(), ValUsage::Read, lvalue_cb); @@ -2939,6 +2890,11 @@ void MIR_SortBlocks(const StaticTraitResolve& resolve, const ::HIR::ItemPath& pa for(auto dst : te.targets) todo.push_back(Todo { dst, ++branches, info.level + 1 }); ), + (SwitchValue, + for(auto dst : te.targets) + todo.push_back(Todo { dst, ++branches, info.level + 1 }); + todo.push_back(Todo { te.def_target, info.branch_count, info.level + 1 }); + ), (Call, todo.push_back(Todo { te.ret_block, info.branch_count, info.level + 1 }); todo.push_back(Todo { te.panic_block, ++branches, info.level + 1 }); @@ -2963,32 +2919,9 @@ void MIR_SortBlocks(const StaticTraitResolve& resolve, const ::HIR::ItemPath& pa { auto fix_bb_idx = [&](auto idx){ return ::std::find(idxes.begin(), idxes.end(), idx) - idxes.begin(); }; new_block_list.push_back( mv$(fcn.blocks[idx]) ); - TU_MATCHA( (new_block_list.back().terminator), (te), - (Incomplete, - ), - (Return, - ), - (Diverge, - ), - (Goto, + visit_terminator_target_mut(new_block_list.back().terminator, [&](auto& te){ te = fix_bb_idx(te); - ), - (Panic, - te.dst = fix_bb_idx(te.dst); - ), - (If, - te.bb0 = fix_bb_idx(te.bb0); - te.bb1 = fix_bb_idx(te.bb1); - ), - (Switch, - for(auto& tgt : te.targets) - tgt = fix_bb_idx(tgt); - ), - (Call, - te.ret_block = fix_bb_idx(te.ret_block); - te.panic_block = fix_bb_idx(te.panic_block); - ) - ) + }); } fcn.blocks = mv$(new_block_list); } diff --git a/src/trans/codegen_c.cpp b/src/trans/codegen_c.cpp index be34e3db..c554d4ab 100644 --- a/src/trans/codegen_c.cpp +++ b/src/trans/codegen_c.cpp @@ -1386,6 +1386,7 @@ namespace { m_of << "\tbool df" << i << " = " << code->drop_flags[i] << ";\n"; } + if( false ) { m_of << "#if 0\n"; auto nodes = MIR_To_Structured(*code); @@ -1445,7 +1446,7 @@ namespace { auto it = m_enum_repr_cache.find( ty.m_data.as_Path().path.m_data.as_Generic() ); if( it != m_enum_repr_cache.end() ) { - MIR_ASSERT(mir_res, e.targets.size() == 2, ""); + MIR_ASSERT(mir_res, e.targets.size() == 2, "Non-zero optimised type a variant count that isn't 2"); m_of << "\tif("; emit_lvalue(e.val); emit_nonzero_path(it->second); m_of << ")\n"; m_of << "\t\tgoto bb" << e.targets[1] << ";\n"; m_of << "\telse\n"; @@ -1470,6 +1471,9 @@ namespace { m_of << "\t}\n"; } ), + (SwitchValue, + MIR_TODO(mir_res, "SwitchValue in C codegen"); + ), (Call, emit_term_call(mir_res, e, 1); m_of << "\tgoto bb" << e.ret_block << ";\n"; @@ -1525,6 +1529,9 @@ namespace { ), (Switch, //assert(i == e.nodes.size()-1 && "Switch"); + ), + (SwitchValue, + //assert(i == e.nodes.size()-1 && "Switch"); ) ) } diff --git a/src/trans/codegen_c_structured.cpp b/src/trans/codegen_c_structured.cpp index e89d7589..888f9a26 100644 --- a/src/trans/codegen_c_structured.cpp +++ b/src/trans/codegen_c_structured.cpp @@ -191,6 +191,9 @@ public: refs.push_back(Node::make_Switch({ exit_bb, &te.val, mv$(arms) })); stop = true; ), + (SwitchValue, + TODO(Span(), "SwitchValue"); + ), (Call, // NOTE: Let the panic arm just be a goto bb_idx = te.ret_block; @@ -260,6 +263,11 @@ public: for(auto tgt : te.targets) conv.m_block_ref_count[tgt] += 1; ), + (SwitchValue, + for(auto tgt : te.targets) + conv.m_block_ref_count[tgt] += 1; + conv.m_block_ref_count[te.def_target] += 1; + ), (Call, conv.m_block_ref_count[te.ret_block] += 1; conv.m_block_ref_count[te.panic_block] += 1; diff --git a/src/trans/enumerate.cpp b/src/trans/enumerate.cpp index fb577959..41489e2b 100644 --- a/src/trans/enumerate.cpp +++ b/src/trans/enumerate.cpp @@ -935,6 +935,9 @@ void Trans_Enumerate_Types(EnumState& state) (Switch, H::visit_lvalue(tv,pp,fcn, te.val); ), + (SwitchValue, + H::visit_lvalue(tv,pp,fcn, te.val); + ), (Call, if( te.fcn.is_Value() ) H::visit_lvalue(tv,pp,fcn, te.fcn.as_Value()); @@ -1476,6 +1479,9 @@ void Trans_Enumerate_FillFrom_MIR(EnumState& state, const ::MIR::Function& code, (Switch, Trans_Enumerate_FillFrom_MIR_LValue(state, e.val, pp); ), + (SwitchValue, + Trans_Enumerate_FillFrom_MIR_LValue(state, e.val, pp); + ), (Call, Trans_Enumerate_FillFrom_MIR_LValue(state, e.ret_val, pp); TU_MATCHA( (e.fcn), (e2), diff --git a/src/trans/monomorphise.cpp b/src/trans/monomorphise.cpp index f708060d..b752a5bc 100644 --- a/src/trans/monomorphise.cpp +++ b/src/trans/monomorphise.cpp @@ -295,6 +295,14 @@ namespace { e.targets }); ), + (SwitchValue, + terminator = ::MIR::Terminator::make_SwitchValue({ + monomorph_LValue(resolve, params, e.val), + e.def_target, + e.targets, + e.values.clone() + }); + ), (Call, struct H { static ::MIR::CallTarget monomorph_calltarget(const ::StaticTraitResolve& resolve, const Trans_Params& params, const ::MIR::CallTarget& ct) { |