diff options
author | John Hodge <tpg@mutabah.net> | 2016-12-17 18:54:11 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2016-12-17 18:54:11 +0800 |
commit | 1d0df81902d38302865473201b76fb03d0bc2b45 (patch) | |
tree | 94bfed85e0c994792c570f72b8c86ccaf6f7916a /src | |
parent | e6116ce077b1f99fe3e510e23bdb5c4646adbcca (diff) | |
download | mrust-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.cpp | 18 |
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) ); } |