diff options
author | John Hodge <tpg@ucc.asn.au> | 2017-12-03 10:07:58 +0800 |
---|---|---|
committer | John Hodge <tpg@ucc.asn.au> | 2017-12-03 10:07:58 +0800 |
commit | 07669e84792a385a39d90d1f2226c4021dd325e3 (patch) | |
tree | a1b43595f9847888cb48e406157b71f2487dce7f /src | |
parent | 0a198f183e0ae0a6a371c5a569f0a2fc4bb26d5a (diff) | |
download | mrust-07669e84792a385a39d90d1f2226c4021dd325e3.tar.gz |
MIR Optimise - Tweaks to DeTemporary pass
Diffstat (limited to 'src')
-rw-r--r-- | src/mir/optimise.cpp | 18 |
1 files changed, 15 insertions, 3 deletions
diff --git a/src/mir/optimise.cpp b/src/mir/optimise.cpp index e83f0ee1..2324a4c3 100644 --- a/src/mir/optimise.cpp +++ b/src/mir/optimise.cpp @@ -75,7 +75,8 @@ namespace { (Static, ), (Field, - return visit_mir_lvalue_mut(*e.val, u, cb); + // HACK: If "moving", use a "Read" value usage (covers some quirks) + return visit_mir_lvalue_mut(*e.val, u == ValUsage::Move ? ValUsage::Read : u, cb); ), (Deref, return visit_mir_lvalue_mut(*e.val, ValUsage::Read, cb); @@ -1253,6 +1254,7 @@ bool MIR_Optimise_DeTemporary(::MIR::TypeResolve& state, ::MIR::Function& fcn) { auto& bb = fcn.blocks[bb_idx]; // TODO: Store statement index, to allow deleting the statement if the value is !Copy + ::std::vector<unsigned> to_delete; ::std::map<unsigned,unsigned> local_assignments; // Local index to statement // Since the passed lvalue was mutated (or borrowed), check if that invalidates part of the above cache. auto check_invalidates = [&](const ::MIR::LValue& lv) { @@ -1283,7 +1285,7 @@ bool MIR_Optimise_DeTemporary(::MIR::TypeResolve& state, ::MIR::Function& fcn) } }; auto replace_cb = [&](auto& lv, auto use) { - if( lv.is_Local() && use == ValUsage::Read ) + if( lv.is_Local() && (use == ValUsage::Read || use == ValUsage::Move) ) { auto it = local_assignments.find(lv.as_Local()); if( it != local_assignments.end() ) @@ -1291,13 +1293,16 @@ bool MIR_Optimise_DeTemporary(::MIR::TypeResolve& state, ::MIR::Function& fcn) 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()]) ) { - local_assignments.erase(it); + // TODO: ::Move is used for field accesses, even if the value is !Copy if( use == ValUsage::Move ) { + to_delete.push_back(it->second); + local_assignments.erase(it); DEBUG(state << lv << " -> " << new_lv << " (and erase)"); } else { + local_assignments.erase(it); DEBUG(state << lv << " kept, !Copy and not moved"); return false; } @@ -1381,6 +1386,13 @@ bool MIR_Optimise_DeTemporary(::MIR::TypeResolve& state, ::MIR::Function& fcn) state.set_cur_stmt_term(bb_idx); DEBUG(state << bb.terminator); visit_mir_lvalues_mut(bb.terminator, replace_cb); + + ::std::sort(to_delete.begin(), to_delete.end()); + while(!to_delete.empty()) + { + bb.statements.erase( bb.statements.begin() + to_delete.back() ); + to_delete.pop_back(); + } } return changed; |