summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2018-01-14 18:09:57 +0800
committerJohn Hodge <tpg@mutabah.net>2018-01-14 18:09:57 +0800
commit9296cc9b7b3cc3d115e4cc31b278e7c2e68c41a2 (patch)
tree0fc99f4cef343c8f89e126e53c37ed74209df3d4 /src
parentf6931f226016259bbbf9c521d3cd44e38cca202b (diff)
downloadmrust-9296cc9b7b3cc3d115e4cc31b278e7c2e68c41a2.tar.gz
MIR Optimise - Dead assignment removal (minimally tested)
Diffstat (limited to 'src')
-rw-r--r--src/mir/optimise.cpp58
1 files changed, 58 insertions, 0 deletions
diff --git a/src/mir/optimise.cpp b/src/mir/optimise.cpp
index 4c2da555..552bc157 100644
--- a/src/mir/optimise.cpp
+++ b/src/mir/optimise.cpp
@@ -502,6 +502,7 @@ bool MIR_Optimise_CommonStatements(::MIR::TypeResolve& state, ::MIR::Function& f
bool MIR_Optimise_UnifyBlocks(::MIR::TypeResolve& state, ::MIR::Function& fcn);
bool MIR_Optimise_ConstPropagte(::MIR::TypeResolve& state, ::MIR::Function& fcn);
bool MIR_Optimise_DeadDropFlags(::MIR::TypeResolve& state, ::MIR::Function& fcn);
+bool MIR_Optimise_DeadAssignments(::MIR::TypeResolve& state, ::MIR::Function& fcn);
bool MIR_Optimise_GarbageCollect_Partial(::MIR::TypeResolve& state, ::MIR::Function& fcn);
bool MIR_Optimise_GarbageCollect(::MIR::TypeResolve& state, ::MIR::Function& fcn);
@@ -608,6 +609,8 @@ void MIR_Optimise(const StaticTraitResolve& resolve, const ::HIR::ItemPath& path
change_happened |= MIR_Optimise_UnifyBlocks(state, fcn);
// >> Remove assignments of unsed drop flags
change_happened |= MIR_Optimise_DeadDropFlags(state, fcn);
+ // >> Remove assignments that are never read
+ change_happened |= MIR_Optimise_DeadAssignments(state, fcn);
#if CHECK_AFTER_ALL
MIR_Validate(resolve, path, fcn, args, ret_type);
@@ -2875,6 +2878,61 @@ bool MIR_Optimise_DeadDropFlags(::MIR::TypeResolve& state, ::MIR::Function& fcn)
return removed_statement;
}
+// --------------------------------------------------------------------
+// Remove unread assignments of locals (and replaced assignments of anything?)
+// --------------------------------------------------------------------
+bool MIR_Optimise_DeadAssignments(::MIR::TypeResolve& state, ::MIR::Function& fcn)
+{
+ bool changed = false;
+ TRACE_FUNCTION_FR("", changed);
+
+ // Find any locals that are never read, and delete their assignments.
+
+ // Per-local flag indicating that the particular local is read.
+ ::std::vector<bool> read_locals( fcn.locals.size() );
+ for(const auto& bb : fcn.blocks)
+ {
+ auto cb = [&](const ::MIR::LValue& lv, ValUsage vu) {
+ if( lv.is_Local() ) {
+ read_locals[lv.as_Local()] = true;
+ }
+ return false;
+ };
+ for(const auto& stmt : bb.statements)
+ {
+ if( stmt.is_Assign() && stmt.as_Assign().dst.is_Local() )
+ {
+ visit_mir_lvalues(stmt.as_Assign().src, cb);
+ }
+ else
+ {
+ visit_mir_lvalues(stmt, cb);
+ }
+ }
+ visit_mir_lvalues(bb.terminator, cb);
+ }
+
+ for(auto& bb : fcn.blocks)
+ {
+ for(auto it = bb.statements.begin(); it != bb.statements.end(); )
+ {
+ state.set_cur_stmt(&bb - &fcn.blocks.front(), it - bb.statements.begin());
+ if( it->is_Assign() && it->as_Assign().dst.is_Local() && read_locals[it->as_Assign().dst.as_Local()] == false )
+ {
+ DEBUG(state << "Unread assignment, remove - " << *it);
+ it = bb.statements.erase(it);
+ changed = true;
+ continue ;
+ }
+ ++ it;
+ }
+ }
+
+ // Locate assignments of locals then find the next assignment or read.
+
+ return changed;
+}
+
// --------------------------------------------------------------------
// Clear all unused blocks