diff options
author | John Hodge <tpg@ucc.asn.au> | 2017-11-25 13:41:30 +0800 |
---|---|---|
committer | John Hodge <tpg@ucc.asn.au> | 2017-11-25 13:41:30 +0800 |
commit | eea1a18bbca15f672a10fb979880a15ab05d46bc (patch) | |
tree | 4f8885a25ba823d27c8d7d21c230da1e0ff2b6bb /src | |
parent | bb76e8809d8dd66de78fab3f16c5f8744f188fae (diff) | |
download | mrust-eea1a18bbca15f672a10fb979880a15ab05d46bc.tar.gz |
MIR Optimise - Tweaking to DeTemporary
Diffstat (limited to 'src')
-rw-r--r-- | src/mir/optimise.cpp | 30 |
1 files changed, 22 insertions, 8 deletions
diff --git a/src/mir/optimise.cpp b/src/mir/optimise.cpp index 1d66981a..00ad19b0 100644 --- a/src/mir/optimise.cpp +++ b/src/mir/optimise.cpp @@ -234,7 +234,7 @@ namespace { visit_mir_lvalue_mut(e.fcn.as_Value(), ValUsage::Read, cb); } for(auto& v : e.args) - visit_mir_lvalue_mut(v, ValUsage::Read, cb); + visit_mir_lvalue_mut(v, ValUsage::Move, cb); visit_mir_lvalue_mut(e.ret_val, ValUsage::Write, cb); ) ) @@ -1286,10 +1286,18 @@ bool MIR_Optimise_DeTemporary(::MIR::TypeResolve& state, ::MIR::Function& fcn) if( it != local_assignments.end() ) { auto new_lv = bb.statements.at( it->second ).as_Assign().src.as_Use().clone(); - if( !state.m_resolve.type_is_copy(state.sp, fcn.locals[lv.as_Local()]) && use == ValUsage::Move ) + if( !state.m_resolve.type_is_copy(state.sp, fcn.locals[lv.as_Local()]) ) { local_assignments.erase(it); - DEBUG(state << lv << " -> " << new_lv << " (and erase)"); + if( use == ValUsage::Move ) + { + DEBUG(state << lv << " -> " << new_lv << " (and erase)"); + } + else + { + DEBUG(state << lv << " kept, !Copy and not moved"); + return false; + } } else { @@ -1309,8 +1317,11 @@ bool MIR_Optimise_DeTemporary(::MIR::TypeResolve& state, ::MIR::Function& fcn) // 1. Replace any referenced locals with contents of a record of the local values. // > Don't do the replacement if the source could have changed visit_mir_lvalues_mut(stmt, replace_cb); + // 2. If it's an assignment of the form Local(N) = LValue, keep a record of that. // > If a local is borrowed, wipe that local's record + bool something_to_add = false; + ::std::pair<unsigned,unsigned> to_add; if(const auto* e = stmt.opt_Assign()) { if( const auto* se = e->src.opt_Borrow() ) @@ -1324,12 +1335,10 @@ bool MIR_Optimise_DeTemporary(::MIR::TypeResolve& state, ::MIR::Function& fcn) { if( e->src.is_Use() ) { - local_assignments[e->dst.as_Local()] = stmt_idx; - } - else - { - local_assignments.erase( e->dst.as_Local() ); + to_add = ::std::make_pair(e->dst.as_Local(), stmt_idx); + something_to_add = true; } + local_assignments.erase( e->dst.as_Local() ); } check_invalidates(e->dst); @@ -1352,6 +1361,11 @@ bool MIR_Optimise_DeTemporary(::MIR::TypeResolve& state, ::MIR::Function& fcn) check_invalidates(lv); return true; }); + + if( something_to_add ) { + DEBUG(state << "Record Local(" << to_add.first << ") set from here"); + local_assignments.insert(to_add); + } } state.set_cur_stmt_term(bb_idx); DEBUG(state << bb.terminator); |