summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Hodge <tpg@ucc.asn.au>2017-04-20 09:56:37 +0800
committerJohn Hodge <tpg@ucc.asn.au>2017-04-20 09:56:37 +0800
commit6f5792ac00800b1a28b8c9c81eb80046f37b2f03 (patch)
tree7dab4bb8bcb849dd579200d5f13a8d166dc87098
parent579327643e143da3144a397723be8bd34dcd6dc2 (diff)
downloadmrust-6f5792ac00800b1a28b8c9c81eb80046f37b2f03.tar.gz
MIR Check Full - Mask values based on calculated lifetimes
-rw-r--r--src/mir/check_full.cpp50
1 files changed, 49 insertions, 1 deletions
diff --git a/src/mir/check_full.cpp b/src/mir/check_full.cpp
index e5230b78..96da8a74 100644
--- a/src/mir/check_full.cpp
+++ b/src/mir/check_full.cpp
@@ -511,7 +511,8 @@ void MIR_Validate_FullValState(::MIR::TypeResolve& mir_res, const ::MIR::Functio
// Determine value lifetimes (BBs in which Copy values are valid)
// - Used to mask out Copy value (prevents combinatorial explosion)
- //auto lifetimes = MIR_Helper_GetLifetimes(mir_res, fcn, /*dump_debug=*/false);
+ auto lifetimes = MIR_Helper_GetLifetimes(mir_res, fcn, /*dump_debug=*/true);
+ DEBUG(lifetimes.m_block_offsets);
ValueStates state;
state.arguments.resize( mir_res.m_args.size(), State(true) );
@@ -527,6 +528,53 @@ void MIR_Validate_FullValState(::MIR::TypeResolve& mir_res, const ::MIR::Functio
auto state = mv$(todo_queue.back().second);
todo_queue.pop_back();
+ // Mask off any values which aren't valid in the first statement of this block
+ {
+ for(unsigned i = 0; i < state.vars.size(); i ++)
+ {
+ /*if( !variables_copy[i] )
+ {
+ // Not Copy, don't apply masking
+ }
+ else*/ if( ! state.vars[i].is_valid() )
+ {
+ // Already invalid
+ }
+ else if( lifetimes.var_valid(i, cur_block, 0) )
+ {
+ // Expected to be valid in this block, leave as-is
+ }
+ else
+ {
+ // Copy value not used at/after this block, mask to false
+ DEBUG("BB" << cur_block << " - var$" << i << " - Outside lifetime, discard");
+ state.vars[i] = State(false);
+ }
+ }
+ for(unsigned i = 0; i < state.temporaries.size(); i ++)
+ {
+ /*if( !variables_copy[i] )
+ {
+ // Not Copy, don't apply masking
+ }
+ else*/ if( ! state.temporaries[i].is_valid() )
+ {
+ // Already invalid
+ }
+ else if( lifetimes.tmp_valid(i, cur_block, 0) )
+ {
+ // Expected to be valid in this block, leave as-is
+ }
+ else
+ {
+ // Copy value not used at/after this block, mask to false
+ DEBUG("BB" << cur_block << " - tmp$" << i << " - Outside lifetime, discard");
+ state.temporaries[i] = State(false);
+ }
+ }
+ }
+
+ // If this state already exists in the map, skip
if( ! block_entry_states[cur_block].add_state(state) )
{
continue ;