summaryrefslogtreecommitdiff
path: root/src/mir/optimise.cpp
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2018-12-30 10:35:38 +0800
committerJohn Hodge <tpg@mutabah.net>2018-12-30 10:35:38 +0800
commitc2af54e57545b55be1a5c32cfe4ffbc4b6e114a4 (patch)
tree71f79545f5f692ab57fee7f5c2b6a75377553926 /src/mir/optimise.cpp
parentc39ca5729eb2782e4286f3e582009e43482ebdc7 (diff)
downloadmrust-c2af54e57545b55be1a5c32cfe4ffbc4b6e114a4.tar.gz
MIR Optimise - constant evaluation: addition
Diffstat (limited to 'src/mir/optimise.cpp')
-rw-r--r--src/mir/optimise.cpp128
1 files changed, 69 insertions, 59 deletions
diff --git a/src/mir/optimise.cpp b/src/mir/optimise.cpp
index 80bca08d..67a5d4a4 100644
--- a/src/mir/optimise.cpp
+++ b/src/mir/optimise.cpp
@@ -2219,75 +2219,85 @@ bool MIR_Optimise_ConstPropagte(::MIR::TypeResolve& state, ::MIR::Function& fcn)
const auto& val_l = se.val_l.as_Constant();
const auto& val_r = se.val_r.as_Constant();
- ::MIR::Constant new_value;
- bool replace = false;
- switch(se.op)
+ if( val_l.is_Const() || val_r.is_Const() )
{
- case ::MIR::eBinOp::EQ:
- if( val_l.is_Const() || val_r.is_Const() )
- ;
- else
+ }
+ else
+ {
+ struct H {
+ static int64_t truncate_s(::HIR::CoreType ct, int64_t v) {
+ return v;
+ }
+ static uint64_t truncate_u(::HIR::CoreType ct, uint64_t v) {
+ switch(ct)
+ {
+ case ::HIR::CoreType::U8: return v & 0xFF;
+ case ::HIR::CoreType::U16: return v & 0xFFFF;
+ case ::HIR::CoreType::U32: return v & 0xFFFFFFFF;
+ case ::HIR::CoreType::U64: return v;
+ case ::HIR::CoreType::U128: return v;
+ case ::HIR::CoreType::Usize: return v;
+ case ::HIR::CoreType::Char:
+ //MIR_BUG(state, "Invalid use of operator on char");
+ break;
+ default:
+ // Invalid type for Uint literal
+ break;
+ }
+ return v;
+ }
+ };
+ ::MIR::Constant new_value;
+ switch(se.op)
{
- replace = true;
+ case ::MIR::eBinOp::EQ:
new_value = ::MIR::Constant::make_Bool({val_l == val_r});
- }
- break;
- case ::MIR::eBinOp::NE:
- if( val_l.is_Const() || val_r.is_Const() )
- ;
- else
- {
- replace = true;
+ break;
+ case ::MIR::eBinOp::NE:
new_value = ::MIR::Constant::make_Bool({val_l != val_r});
- }
- break;
- case ::MIR::eBinOp::LT:
- if( val_l.is_Const() || val_r.is_Const() )
- ;
- else
- {
- replace = true;
+ break;
+ case ::MIR::eBinOp::LT:
new_value = ::MIR::Constant::make_Bool({val_l < val_r});
- }
- break;
- case ::MIR::eBinOp::LE:
- if( val_l.is_Const() || val_r.is_Const() )
- ;
- else
- {
- replace = true;
+ break;
+ case ::MIR::eBinOp::LE:
new_value = ::MIR::Constant::make_Bool({val_l <= val_r});
- }
- break;
- case ::MIR::eBinOp::GT:
- if( val_l.is_Const() || val_r.is_Const() )
- ;
- else
- {
- replace = true;
+ break;
+ case ::MIR::eBinOp::GT:
new_value = ::MIR::Constant::make_Bool({val_l > val_r});
- }
- break;
- case ::MIR::eBinOp::GE:
- if( val_l.is_Const() || val_r.is_Const() )
- ;
- else
- {
- replace = true;
+ break;
+ case ::MIR::eBinOp::GE:
new_value = ::MIR::Constant::make_Bool({val_l >= val_r});
+ break;
+
+ case ::MIR::eBinOp::ADD:
+ MIR_ASSERT(state, val_l.tag() == val_r.tag(), "Mismatched types for eBinOp::ADD - " << val_l << " + " << val_r);
+ //{TU_MATCH_HDRA( (val_l, val_r), {)
+ {TU_MATCH_HDRA( (val_l), {)
+ default:
+ break;
+ // TU_ARMav(Int, (le, re)) {
+ TU_ARMA(Int, le) { const auto& re = val_r.as_Int();
+ MIR_ASSERT(state, le.t == re.t, "Mismatched types for eBinOp::ADD - " << val_l << " + " << val_r);
+ new_value = ::MIR::Constant::make_Int({ H::truncate_s(le.t, le.v + re.v) });
+ }
+ TU_ARMA(Uint, le) { const auto& re = val_r.as_Uint();
+ MIR_ASSERT(state, le.t == re.t, "Mismatched types for eBinOp::ADD - " << val_l << " + " << val_r);
+ new_value = ::MIR::Constant::make_Uint({ H::truncate_u(le.t, le.v + re.v) });
+ }
+ }}
+ break;
+ // TODO: Other binary operations
+ // Could emit a TODO?
+ default:
+ break;
}
- break;
- // TODO: Other binary operations
- // Could emit a TODO?
- default:
- break;
- }
- if( replace )
- {
- DEBUG(state << " " << e->src << " = " << new_value);
- e->src = mv$(new_value);
- changed = true;
+ if( new_value != ::MIR::Constant() )
+ {
+ DEBUG(state << " " << e->src << " = " << new_value);
+ e->src = mv$(new_value);
+ changed = true;
+ }
}
}
),