summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2016-12-17 18:54:11 +0800
committerJohn Hodge <tpg@mutabah.net>2016-12-17 18:54:11 +0800
commit1d0df81902d38302865473201b76fb03d0bc2b45 (patch)
tree94bfed85e0c994792c570f72b8c86ccaf6f7916a /src
parente6116ce077b1f99fe3e510e23bdb5c4646adbcca (diff)
downloadmrust-1d0df81902d38302865473201b76fb03d0bc2b45.tar.gz
MIR Gen - Unlink return block from diverging functions (enables better optimisations)
Diffstat (limited to 'src')
-rw-r--r--src/mir/from_hir.cpp18
1 files changed, 17 insertions, 1 deletions
diff --git a/src/mir/from_hir.cpp b/src/mir/from_hir.cpp
index 9db4b115..98d339e3 100644
--- a/src/mir/from_hir.cpp
+++ b/src/mir/from_hir.cpp
@@ -1406,8 +1406,9 @@ namespace {
auto next_block = m_builder.new_bb_unlinked();
auto res = m_builder.new_temporary( node.m_res_type );
+ bool unconditional_diverge = false;
+
// Emit intrinsics as a special call type
- // TODO: Should the parameters be stored? (trans has get_lvalue_type, so no 100% needed)
if( node.m_path.m_data.is_Generic() )
{
const auto& gpath = node.m_path.m_data.as_Generic();
@@ -1420,6 +1421,11 @@ namespace {
mv$(values)
}));
}
+
+ if( fcn.m_return.m_data.is_Diverge() )
+ {
+ unconditional_diverge = true;
+ }
}
// If the call wasn't to an intrinsic, emit it as a path
@@ -1437,6 +1443,16 @@ namespace {
m_builder.end_block( ::MIR::Terminator::make_Diverge({}) );
m_builder.set_cur_block( next_block );
+
+ // If the function doesn't return, early-terminate the return block.
+ if( unconditional_diverge )
+ {
+ m_builder.end_block( ::MIR::Terminator::make_Diverge({}) );
+ m_builder.set_cur_block( m_builder.new_bb_unlinked() );
+ }
+ else
+ {
+ }
m_builder.set_result( node.span(), mv$(res) );
}