summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohn Hodge <tpg@ucc.asn.au>2017-12-02 08:32:23 +0800
committerJohn Hodge <tpg@ucc.asn.au>2017-12-02 08:32:23 +0800
commit1887d94d65bb38624f03944597662244a92cfd80 (patch)
tree8e79f0896b51cb104995ea58f03c5614ba4cccf2 /src
parentb590a2adb49ba146aa2d866af4e47c7d9427acf0 (diff)
downloadmrust-1887d94d65bb38624f03944597662244a92cfd80.tar.gz
MIR Optimise - Fix infinite replacement
Diffstat (limited to 'src')
-rw-r--r--src/mir/optimise.cpp11
1 files changed, 11 insertions, 0 deletions
diff --git a/src/mir/optimise.cpp b/src/mir/optimise.cpp
index 00ad19b0..e83f0ee1 100644
--- a/src/mir/optimise.cpp
+++ b/src/mir/optimise.cpp
@@ -62,6 +62,7 @@ namespace {
bool visit_mir_lvalue_mut(::MIR::LValue& lv, ValUsage u, ::std::function<bool(::MIR::LValue& , ValUsage)> cb)
{
+ //TRACE_FUNCTION_F(lv);
if( cb(lv, u) )
return true;
TU_MATCHA( (lv), (e),
@@ -553,12 +554,14 @@ void MIR_Optimise(const StaticTraitResolve& resolve, const ::HIR::ItemPath& path
MIR_Validate(resolve, path, fcn, args, ret_type);
#endif
+#if 1
// Attempt to remove useless temporaries
while( MIR_Optimise_DeTemporary(state, fcn) )
change_happened = true;
#if CHECK_AFTER_ALL
MIR_Validate(resolve, path, fcn, args, ret_type);
#endif
+#endif
// >> Replace values from composites if they're known
// - Undoes the inefficiencies from the `match (a, b) { ... }` pattern
@@ -1305,6 +1308,7 @@ bool MIR_Optimise_DeTemporary(::MIR::TypeResolve& state, ::MIR::Function& fcn)
}
lv = mv$(new_lv);
changed = true;
+ return true;
}
}
return false;
@@ -1337,11 +1341,18 @@ bool MIR_Optimise_DeTemporary(::MIR::TypeResolve& state, ::MIR::Function& fcn)
{
to_add = ::std::make_pair(e->dst.as_Local(), stmt_idx);
something_to_add = true;
+
+ if( visit_mir_lvalues(e->src, [&](const auto& lv, auto ){ return lv == e->dst; }) )
+ {
+ DEBUG(state << "Assignment to slot used in source, can't use");
+ something_to_add = false;
+ }
}
local_assignments.erase( e->dst.as_Local() );
}
check_invalidates(e->dst);
+ // Remove no-op assignents
if( TU_TEST1(e->src, Use, == e->dst) ) {
bb.statements.erase(bb.statements.begin() + stmt_idx);
stmt_idx -= 1;