summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Hodge <tpg@ucc.asn.au>2019-08-10 10:23:00 +0800
committerJohn Hodge <tpg@ucc.asn.au>2019-08-10 10:23:00 +0800
commit5467b92813e62a7efbce87c5082c96c6fe155de7 (patch)
tree59cbcbeada782cd5ec23aa17201627b7d299a220
parent657a5a99edf0722c9db5956ca9d42db65c9e683e (diff)
downloadmrust-5467b92813e62a7efbce87c5082c96c6fe155de7.tar.gz
MIR Optimise - Fix mis-optimisation in mpsc
-rw-r--r--src/mir/optimise.cpp20
1 files changed, 11 insertions, 9 deletions
diff --git a/src/mir/optimise.cpp b/src/mir/optimise.cpp
index c4f73014..54c2d22a 100644
--- a/src/mir/optimise.cpp
+++ b/src/mir/optimise.cpp
@@ -1502,12 +1502,12 @@ namespace {
return IterPathRes::Complete;
}
- ::std::function<bool(const ::MIR::LValue& , ValUsage)> check_invalidates_lvalue_cb(const ::MIR::LValue& val)
+ ::std::function<bool(const ::MIR::LValue& , ValUsage)> check_invalidates_lvalue_cb(const ::MIR::LValue& val, bool also_read=false)
{
- bool has_index = ::std::any_of(val.m_wrappers.begin(), val.m_wrappers.end(), [&](const auto& w){ return w.is_Index(); });
+ bool has_index = ::std::any_of(val.m_wrappers.begin(), val.m_wrappers.end(), [](const auto& w){ return w.is_Index(); });
// Value is invalidated if it's used with ValUsage::Write or ValUsage::Borrow
// - Same applies to any component of the lvalue
- return [&val,has_index](const ::MIR::LValue& lv, ValUsage vu) {
+ return [&val,has_index,also_read](const ::MIR::LValue& lv, ValUsage vu) {
switch(vu)
{
case ValUsage::Move: // A move can invalidate
@@ -1533,18 +1533,20 @@ namespace {
}
break;
case ValUsage::Read:
+ if( also_read )
+ return true;
break;
}
return false;
};
}
- bool check_invalidates_lvalue(const ::MIR::Statement& stmt, const ::MIR::LValue& val)
+ bool check_invalidates_lvalue(const ::MIR::Statement& stmt, const ::MIR::LValue& val, bool also_read=false)
{
- return visit_mir_lvalues(stmt, check_invalidates_lvalue_cb(val));
+ return visit_mir_lvalues(stmt, check_invalidates_lvalue_cb(val, also_read));
}
- bool check_invalidates_lvalue(const ::MIR::Terminator& term, const ::MIR::LValue& val)
+ bool check_invalidates_lvalue(const ::MIR::Terminator& term, const ::MIR::LValue& val, bool also_read=false)
{
- return visit_mir_lvalues(term, check_invalidates_lvalue_cb(val));
+ return visit_mir_lvalues(term, check_invalidates_lvalue_cb(val, also_read));
}
}
@@ -1646,8 +1648,8 @@ bool MIR_Optimise_DeTemporary_SingleSetAndUse(::MIR::TypeResolve& state, ::MIR::
// - Iterate the path(s) between the two statements to check if the destination would be invalidated
// > The iterate function doesn't (yet) support following BB chains, so assume invalidated if over a jump.
bool invalidated = IterPathRes::Complete != iter_path(fcn, slot.set_loc, slot.use_loc,
- [&](auto loc, const auto& stmt)->bool{ return check_invalidates_lvalue(stmt, dst); },
- [&](auto loc, const auto& term)->bool{ return check_invalidates_lvalue(term, dst); }
+ [&](auto loc, const auto& stmt)->bool{ return check_invalidates_lvalue(stmt, dst, /*also_read=*/true); },
+ [&](auto loc, const auto& term)->bool{ return check_invalidates_lvalue(term, dst, /*also_read=*/true); }
);
if( !invalidated )
{