summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2017-02-04 21:29:50 +0800
committerJohn Hodge <tpg@mutabah.net>2017-02-04 21:29:50 +0800
commitabeea0472605262dc35fe9e1bf295f5b0e058ad6 (patch)
tree7ff27f70a78a7794a6e4b415f7810fd644a0bac4
parenta5035a65c2291560e32d5529dc06c90ae45e851f (diff)
downloadmrust-abeea0472605262dc35fe9e1bf295f5b0e058ad6.tar.gz
MIR Optimise - Planning for const propagation, tweak assignment propagation
-rw-r--r--src/mir/optimise.cpp48
1 files changed, 46 insertions, 2 deletions
diff --git a/src/mir/optimise.cpp b/src/mir/optimise.cpp
index e24aa22d..214bb605 100644
--- a/src/mir/optimise.cpp
+++ b/src/mir/optimise.cpp
@@ -1414,6 +1414,45 @@ bool MIR_Optimise_ConstPropagte(::MIR::TypeResolve& state, ::MIR::Function& fcn)
bool changed = false;
TRACE_FUNCTION_FR("", changed);
+ // - Remove calls to `size_of` and `align_of` (replace with value if known)
+ for(auto& bb : fcn.blocks)
+ {
+ if( !bb.terminator.is_Call() )
+ continue ;
+ auto& te = bb.terminator.as_Call();
+ if( !te.fcn.is_Intrinsic() )
+ continue ;
+ const auto& tef = te.fcn.as_Intrinsic();
+ if( tef.name == "size_of" )
+ {
+ //size_t size_val = 0;
+ //if( Target_GetSizeOf(tef.params.m_types.at(0), size_val) )
+ //{
+ // bb.statements.push_back(::MIR::Statement::make_Assign({ mv$(te.ret_val), ::MIR::Constant::make_Uint(size_val) }));
+ // bb.terminator = ::MIR::Terminator::make_Goto(te.ret_block);
+ //}
+ }
+ else if( tef.name == "align_of" )
+ {
+ //size_t size_val = 0;
+ //if( Target_GetAlignOf(tef.params.m_types.at(0), size_val) )
+ //{
+ // bb.statements.push_back(::MIR::Statement::make_Assign({ mv$(te.ret_val), ::MIR::Constant::make_Uint(size_val) }));
+ // bb.terminator = ::MIR::Terminator::make_Goto(te.ret_block);
+ //}
+ }
+ else
+ {
+ // Ignore any other intrinsics
+ }
+ }
+
+ // - Propage constants within BBs
+ // > Evaluate BinOp with known values
+ // > Understand intrinsics like overflowing_* (with correct semantics)
+ // > NOTE: No need to locally stitch blocks, next pass will do that
+ // TODO: Use ValState to do full constant propagation across blocks
+
// 1. Remove based on known booleans within a single block
// - Eliminates `if false`/`if true` branches
for(auto& bb : fcn.blocks)
@@ -1468,6 +1507,7 @@ bool MIR_Optimise_ConstPropagte(::MIR::TypeResolve& state, ::MIR::Function& fcn)
changed = true;
}
}
+
return changed;
}
@@ -1588,8 +1628,10 @@ bool MIR_Optimise_PropagateSingleAssignments(::MIR::TypeResolve& state, ::MIR::F
if( e.src.is_Use() )
{
// Keep the complexity down
- const auto& src = e.src.as_Use();
- if( !( src.is_Temporary() || src.is_Variable() || src.is_Argument() ) )
+ const auto* srcp = &e.src.as_Use();
+ while( srcp->is_Field() )
+ srcp = &*srcp->as_Field().val;
+ if( !( srcp->is_Temporary() || srcp->is_Variable() || srcp->is_Argument() ) )
continue ;
}
// TODO: Allow any rvalue, but that currently breaks due to chaining
@@ -1948,6 +1990,8 @@ bool MIR_Optimise_PropagateSingleAssignments(::MIR::TypeResolve& state, ::MIR::F
}
}
+ // TODO: Run special case replacements for when there's `tmp/var = arg` and `rv = tmp/var`
+
return replacement_happend;
}