diff options
author | John Hodge <tpg@mutabah.net> | 2018-01-14 18:09:57 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2018-01-14 18:09:57 +0800 |
commit | 9296cc9b7b3cc3d115e4cc31b278e7c2e68c41a2 (patch) | |
tree | 0fc99f4cef343c8f89e126e53c37ed74209df3d4 /src | |
parent | f6931f226016259bbbf9c521d3cd44e38cca202b (diff) | |
download | mrust-9296cc9b7b3cc3d115e4cc31b278e7c2e68c41a2.tar.gz |
MIR Optimise - Dead assignment removal (minimally tested)
Diffstat (limited to 'src')
-rw-r--r-- | src/mir/optimise.cpp | 58 |
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 |