summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/hir/serialise.cpp24
-rw-r--r--src/hir_conv/bind.cpp3
-rw-r--r--src/mir/check.cpp17
-rw-r--r--src/mir/check_full.cpp8
-rw-r--r--src/mir/cleanup.cpp3
-rw-r--r--src/mir/dump.cpp18
-rw-r--r--src/mir/helpers.cpp10
-rw-r--r--src/mir/mir.cpp34
-rw-r--r--src/mir/mir.hpp14
-rw-r--r--src/mir/optimise.cpp263
-rw-r--r--src/trans/codegen_c.cpp9
-rw-r--r--src/trans/codegen_c_structured.cpp8
-rw-r--r--src/trans/enumerate.cpp6
-rw-r--r--src/trans/monomorphise.cpp8
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) {