diff options
author | John Hodge <tpg@mutabah.net> | 2018-02-25 15:50:21 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2018-02-25 15:50:21 +0800 |
commit | 2290f46bb3748ca766f0c66ebfdf7b522862ad8c (patch) | |
tree | cc6760f9edb3fa115e270186d194b057c1c4507e /src/mir/optimise.cpp | |
parent | f0635db475fdfa77bbda6313c392589716d5854e (diff) | |
download | mrust-2290f46bb3748ca766f0c66ebfdf7b522862ad8c.tar.gz |
MIR Optimise - Remove no-op assignments
Diffstat (limited to 'src/mir/optimise.cpp')
-rw-r--r-- | src/mir/optimise.cpp | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/src/mir/optimise.cpp b/src/mir/optimise.cpp index 88a073cf..dbc7e9c2 100644 --- a/src/mir/optimise.cpp +++ b/src/mir/optimise.cpp @@ -504,6 +504,7 @@ 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_NoopRemoval(::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); @@ -605,6 +606,8 @@ void MIR_Optimise(const StaticTraitResolve& resolve, const ::HIR::ItemPath& path change_happened |= MIR_Optimise_DeadDropFlags(state, fcn); // >> Remove assignments that are never read change_happened |= MIR_Optimise_DeadAssignments(state, fcn); + // >> Remove no-op assignments + change_happened |= MIR_Optimise_NoopRemoval(state, fcn); #if CHECK_AFTER_ALL MIR_Validate(resolve, path, fcn, args, ret_type); @@ -651,6 +654,7 @@ void MIR_Optimise(const StaticTraitResolve& resolve, const ::HIR::ItemPath& path #endif MIR_Optimise_UnifyBlocks(state, fcn); //MIR_Optimise_ConstPropagte(state, fcn); + MIR_Optimise_NoopRemoval(state, fcn); } @@ -2188,6 +2192,7 @@ bool MIR_Optimise_ConstPropagte(::MIR::TypeResolve& state, ::MIR::Function& fcn) } break; // TODO: Other binary operations + // Could emit a TODO? default: break; } @@ -3234,6 +3239,52 @@ bool MIR_Optimise_DeadAssignments(::MIR::TypeResolve& state, ::MIR::Function& fc } // Locate assignments of locals then find the next assignment or read. + return changed; +} + +// -------------------------------------------------------------------- +// Eliminate no-operation assignments that may have appeared +// -------------------------------------------------------------------- +bool MIR_Optimise_NoopRemoval(::MIR::TypeResolve& state, ::MIR::Function& fcn) +{ + bool changed = false; + TRACE_FUNCTION_FR("", changed); + + // Remove useless operations + for(auto& bb : fcn.blocks) + { + for(auto it = bb.statements.begin(); it != bb.statements.end(); ) + { + // `Value = Use(Value)` + if( it->is_Assign() + && it->as_Assign().src.is_Use() + && it->as_Assign().src.as_Use() == it->as_Assign().dst + ) + { + DEBUG(state << "Useless assignment, remove - " << *it); + it = bb.statements.erase(it); + changed = true; + + continue ; + } + + // `Value = Borrow(Deref(Value))` + if( it->is_Assign() + && it->as_Assign().src.is_Borrow() + && it->as_Assign().src.as_Borrow().val.is_Deref() + && *it->as_Assign().src.as_Borrow().val.as_Deref().val == it->as_Assign().dst + ) + { + DEBUG(state << "Useless assignment (v = &*v), remove - " << *it); + it = bb.statements.erase(it); + changed = true; + + continue ; + } + + ++ it; + } + } return changed; } |