summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mir/check_full.cpp76
1 files changed, 76 insertions, 0 deletions
diff --git a/src/mir/check_full.cpp b/src/mir/check_full.cpp
index 34a14d0c..1703dfd4 100644
--- a/src/mir/check_full.cpp
+++ b/src/mir/check_full.cpp
@@ -76,6 +76,58 @@ namespace
}
bool is_equivalent_to(const ValueStates& x) const
{
+ struct H {
+ static bool equal(const ValueStates& vss_a, const State& a, const ValueStates& vss_b, const State& b)
+ {
+ if( a.index == 0 )
+ {
+ return b.index == 0;
+ }
+ if( a.index == ~0u )
+ {
+ return b.index == ~0u;
+ }
+ if( b.index == 0 || b.index == ~0u )
+ {
+ return false;
+ }
+
+ const auto& states_a = vss_a.inner_states.at( a.index - 1 );
+ const auto& states_b = vss_b.inner_states.at( b.index - 1 );
+ // NOTE: If there's two differen variants, this can happen.
+ if( states_a.size() != states_b.size() )
+ return false;
+
+ for(size_t i = 0; i < states_a.size(); i ++)
+ {
+ if( ! H::equal(vss_a, states_a[i], vss_b, states_b[i]) )
+ return false;
+ }
+ // If the above loop didn't early exit, the two states are equal
+ return true;
+ }
+ };
+
+ if( ! H::equal(*this, return_value, x, x.return_value) )
+ return false;
+ assert(vars.size() == x.vars.size());
+ for(size_t i = 0; i < vars.size(); i ++)
+ {
+ if( ! H::equal(*this, vars[i], x, x.vars[i]) )
+ return false;
+ }
+ assert(temporaries.size() == x.temporaries.size());
+ for(size_t i = 0; i < temporaries.size(); i ++)
+ {
+ if( ! H::equal(*this, temporaries[i], x, x.temporaries[i]) )
+ return false;
+ }
+ assert(arguments.size() == x.arguments.size());
+ for(size_t i = 0; i < arguments.size(); i ++)
+ {
+ if( ! H::equal(*this, arguments[i], x, x.arguments[i]) )
+ return false;
+ }
return true;
}
@@ -152,6 +204,8 @@ namespace
used.at(s.index-1) = true;
for(const auto& s : vss.inner_states.at(s.index-1))
mark_from_state(vss, s);
+
+ // TODO: Should this compact composites with all-equal inner states?
}
}
};
@@ -418,6 +472,27 @@ namespace
return os;
}
+namespace std {
+ ostream& operator<<(ostream& os, const ValueStates& x)
+ {
+ auto print_val = [&](auto tag, const State& s) {
+ if(s.is_composite()) {
+ os << tag << "=" << StateFmt(x,s);
+ }
+ else if( s.is_valid() ) {
+ os << tag;
+ }
+ else {
+ }
+ };
+
+ os << "ValueStates(path=[" << x.bb_path << "]";
+ print_val(",rv", x.return_value);
+ os << ")";
+ return os;
+ }
+}
+
// "Executes" the function, keeping track of drop flags and variable validities
void MIR_Validate_FullValState(::MIR::TypeResolve& mir_res, const ::MIR::Function& fcn)
@@ -442,6 +517,7 @@ void MIR_Validate_FullValState(::MIR::TypeResolve& mir_res, const ::MIR::Functio
{
continue ;
}
+ DEBUG("BB" << cur_block << " - " << state);
state.bb_path.push_back( cur_block );
const auto& blk = fcn.blocks.at(cur_block);